diff -rc2N gs241/COPYING gs25/COPYING *** gs241/COPYING --- gs25/COPYING Thu Jul 4 19:02:28 1991 *************** *** 0 **** --- 1,339 ---- + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 675 Mass Ave, Cambridge, MA 02139, USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your + freedom to share and change it. By contrast, the GNU General Public + License is intended to guarantee your freedom to share and change free + software--to make sure the software is free for all its users. This + General Public License applies to most of the Free Software + Foundation's software and to any other program whose authors commit to + using it. (Some other Free Software Foundation software is covered by + the GNU Library General Public License instead.) You can apply it to + your programs, too. + + When we speak of free software, we are referring to freedom, not + price. Our General Public Licenses are designed to make sure that you + have the freedom to distribute copies of free software (and charge for + this service if you wish), that you receive source code or can get it + if you want it, that you can change the software or use pieces of it + in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid + anyone to deny you these rights or to ask you to surrender the rights. + These restrictions translate to certain responsibilities for you if you + distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether + gratis or for a fee, you must give the recipients all the rights that + you have. You must make sure that they, too, receive or can get the + source code. And you must show them these terms so they know their + rights. + + We protect your rights with two steps: (1) copyright the software, and + (2) offer you this license which gives you legal permission to copy, + distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain + that everyone understands that there is no warranty for this free + software. If the software is modified by someone else and passed on, we + want its recipients to know that what they have is not the original, so + that any problems introduced by others will not reflect on the original + authors' reputations. + + Finally, any free program is threatened constantly by software + patents. We wish to avoid the danger that redistributors of a free + program will individually obtain patent licenses, in effect making the + program proprietary. To prevent this, we have made it clear that any + patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and + modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains + a notice placed by the copyright holder saying it may be distributed + under the terms of this General Public License. The "Program", below, + refers to any such program or work, and a "work based on the Program" + means either the Program or any derivative work under copyright law: + that is to say, a work containing the Program or a portion of it, + either verbatim or with modifications and/or translated into another + language. (Hereinafter, translation is included without limitation in + the term "modification".) Each licensee is addressed as "you". + + Activities other than copying, distribution and modification are not + covered by this License; they are outside its scope. The act of + running the Program is not restricted, and the output from the Program + is covered only if its contents constitute a work based on the + Program (independent of having been made by running the Program). + Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's + source code as you receive it, in any medium, provided that you + conspicuously and appropriately publish on each copy an appropriate + copyright notice and disclaimer of warranty; keep intact all the + notices that refer to this License and to the absence of any warranty; + and give any other recipients of the Program a copy of this License + along with the Program. + + You may charge a fee for the physical act of transferring a copy, and + you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion + of it, thus forming a work based on the Program, and copy and + distribute such modifications or work under the terms of Section 1 + above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + + These requirements apply to the modified work as a whole. If + identifiable sections of that work are not derived from the Program, + and can be reasonably considered independent and separate works in + themselves, then this License, and its terms, do not apply to those + sections when you distribute them as separate works. But when you + distribute the same sections as part of a whole which is a work based + on the Program, the distribution of the whole must be on the terms of + this License, whose permissions for other licensees extend to the + entire whole, and thus to each and every part regardless of who wrote it. + + Thus, it is not the intent of this section to claim rights or contest + your rights to work written entirely by you; rather, the intent is to + exercise the right to control the distribution of derivative or + collective works based on the Program. + + In addition, mere aggregation of another work not based on the Program + with the Program (or with a work based on the Program) on a volume of + a storage or distribution medium does not bring the other work under + the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, + under Section 2) in object code or executable form under the terms of + Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + + The source code for a work means the preferred form of the work for + making modifications to it. For an executable work, complete source + code means all the source code for all modules it contains, plus any + associated interface definition files, plus the scripts used to + control compilation and installation of the executable. However, as a + special exception, the source code distributed need not include + anything that is normally distributed (in either source or binary + form) with the major components (compiler, kernel, and so on) of the + operating system on which the executable runs, unless that component + itself accompanies the executable. + + If distribution of executable or object code is made by offering + access to copy from a designated place, then offering equivalent + access to copy the source code from the same place counts as + distribution of the source code, even though third parties are not + compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program + except as expressly provided under this License. Any attempt + otherwise to copy, modify, sublicense or distribute the Program is + void, and will automatically terminate your rights under this License. + However, parties who have received copies, or rights, from you under + this License will not have their licenses terminated so long as such + parties remain in full compliance. + + 5. You are not required to accept this License, since you have not + signed it. However, nothing else grants you permission to modify or + distribute the Program or its derivative works. These actions are + prohibited by law if you do not accept this License. Therefore, by + modifying or distributing the Program (or any work based on the + Program), you indicate your acceptance of this License to do so, and + all its terms and conditions for copying, distributing or modifying + the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the + Program), the recipient automatically receives a license from the + original licensor to copy, distribute or modify the Program subject to + these terms and conditions. You may not impose any further + restrictions on the recipients' exercise of the rights granted herein. + You are not responsible for enforcing compliance by third parties to + this License. + + 7. If, as a consequence of a court judgment or allegation of patent + infringement or for any other reason (not limited to patent issues), + conditions are imposed on you (whether by court order, agreement or + otherwise) that contradict the conditions of this License, they do not + excuse you from the conditions of this License. If you cannot + distribute so as to satisfy simultaneously your obligations under this + License and any other pertinent obligations, then as a consequence you + may not distribute the Program at all. For example, if a patent + license would not permit royalty-free redistribution of the Program by + all those who receive copies directly or indirectly through you, then + the only way you could satisfy both it and this License would be to + refrain entirely from distribution of the Program. + + If any portion of this section is held invalid or unenforceable under + any particular circumstance, the balance of the section is intended to + apply and the section as a whole is intended to apply in other + circumstances. + + It is not the purpose of this section to induce you to infringe any + patents or other property right claims or to contest validity of any + such claims; this section has the sole purpose of protecting the + integrity of the free software distribution system, which is + implemented by public license practices. Many people have made + generous contributions to the wide range of software distributed + through that system in reliance on consistent application of that + system; it is up to the author/donor to decide if he or she is willing + to distribute software through any other system and a licensee cannot + impose that choice. + + This section is intended to make thoroughly clear what is believed to + be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in + certain countries either by patents or by copyrighted interfaces, the + original copyright holder who places the Program under this License + may add an explicit geographical distribution limitation excluding + those countries, so that distribution is permitted only in or among + countries not thus excluded. In such case, this License incorporates + the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions + of the General Public License from time to time. Such new versions will + be similar in spirit to the present version, but may differ in detail to + address new problems or concerns. + + Each version is given a distinguishing version number. If the Program + specifies a version number of this License which applies to it and "any + later version", you have the option of following the terms and conditions + either of that version or of any later version published by the Free + Software Foundation. If the Program does not specify a version number of + this License, you may choose any version ever published by the Free Software + Foundation. + + 10. If you wish to incorporate parts of the Program into other free + programs whose distribution conditions are different, write to the author + to ask for permission. For software which is copyrighted by the Free + Software Foundation, write to the Free Software Foundation; we sometimes + make exceptions for this. Our decision will be guided by the two goals + of preserving the free status of all derivatives of our free software and + of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY + FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN + OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES + PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED + OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS + TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE + PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, + REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING + WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR + REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, + INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING + OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED + TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY + YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER + PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + Appendix: How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest + possible use to the public, the best way to achieve this is to make it + free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest + to attach them to the start of each source file to most effectively + convey the exclusion of warranty; and each file should have at least + the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) 19yy + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + Also add information on how to contact you by electronic and paper mail. + + If the program is interactive, make it output a short notice like this + when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + + The hypothetical commands `show w' and `show c' should show the appropriate + parts of the General Public License. Of course, the commands you use may + be called something other than `show w' and `show c'; they could even be + mouse-clicks or menu items--whatever suits your program. + + You should also get your employer (if you work as a programmer) or your + school, if any, to sign a "copyright disclaimer" for the program, if + necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + + This General Public License does not permit incorporating your program into + proprietary programs. If your program is a subroutine library, you may + consider it more useful to permit linking proprietary applications with the + library. If this is what you want to do, use the GNU Library General + Public License instead of this License. diff -rc2N gs241/Fontmap gs25/Fontmap *** gs241/Fontmap Wed Apr 8 18:27:32 1992 --- gs25/Fontmap Tue Aug 11 03:08:18 1992 *************** *** 29,36 **** % from which a font of a given name should be loaded. % ! % - The name of the Ghostscript font file (a Ghostscript string). ! % The filename should include the extension, which (by convention) ! % is `.gsf'. % % - A terminating semicolon. --- 29,45 ---- % from which a font of a given name should be loaded. % ! % - Information depending on whether this is a real font or a ! % font alias: % + % - For real fonts, the name of the Ghostscript font + % file (a Ghostscript string, enclosed in parentheses). + % The filename should include the extension, which (by + % convention) is `.gsf'. `.pfa' and `.pfb' files are + % also usable as fonts for Ghostscript. + % + % - For font aliases, the name of the font which should + % be used when this one is requested, preceded by a + % `/'. See the entry for Charter below for an example. + % % - A terminating semicolon. *************** *** 70,86 **** /Bookman-DemiItalic (pbkdi.gsf) ; ! /Charter-Roman (bchr.gsf) ; ! /Charter-Italic (bchri.gsf) ; ! /Charter-Bold (bchb.gsf) ; ! /Charter-BoldItalic (bchbi.gsf) ; ! % The converted Courier font has been replaced by a Type 1 font % contributed to the X11R5 distribution; see below. - % Unfortunately, quite a few PostScript files use Courier-Oblique - % rather than Courier-Italic, so we have to keep the old Obliques around. %/Courier (pcrr.gsf) ; ! /Courier-Oblique (pcrro.gsf) ; %/Courier-Bold (pcrb.gsf) ; ! /Courier-BoldOblique (pcrbo.gsf) ; /Helvetica (phvr.gsf) ; --- 79,99 ---- /Bookman-DemiItalic (pbkdi.gsf) ; ! % The converted Bitstream fonts have been replaced by Type 1 fonts ! % contributed to the X11R5 distribution; see below. ! %/Charter-Roman (bchr.gsf) ; ! %/Charter-Italic (bchri.gsf) ; ! %/Charter-Bold (bchb.gsf) ; ! %/Charter-BoldItalic (bchbi.gsf) ; ! % The converted Courier fonts have been replaced by Type 1 fonts % contributed to the X11R5 distribution; see below. %/Courier (pcrr.gsf) ; ! %/Courier-Oblique (pcrro.gsf) ; %/Courier-Bold (pcrb.gsf) ; ! %/Courier-BoldOblique (pcrbo.gsf) ; ! % Quite a few PostScript files reference Courier-Oblique rather than ! % Courier-Italic, so we need some aliases here. ! /Courier-Oblique /Courier-Italic ; ! /Courier-BoldOblique /Courier-BoldItalic ; /Helvetica (phvr.gsf) ; *************** *** 108,114 **** /ZapfChancery (zcr.gsf) ; - /ZapfChancery-MediumItalic (zcri.gsf) ; /ZapfChancery-Oblique (zcro.gsf) ; /ZapfChancery-Bold (zcb.gsf) ; /ZapfDingbats (pzdr.gsf) ; --- 121,128 ---- /ZapfChancery (zcr.gsf) ; /ZapfChancery-Oblique (zcro.gsf) ; /ZapfChancery-Bold (zcb.gsf) ; + % Some PostScript files reference the MediumItalic font.... + /ZapfChancery-MediumItalic /ZapfChancery-Oblique ; /ZapfDingbats (pzdr.gsf) ; *************** *** 121,124 **** --- 135,163 ---- % + % The following notice accompanied the Charter fonts. + % + % (c) Copyright 1989-1992, Bitstream Inc., Cambridge, MA. + % + % You are hereby granted permission under all Bitstream propriety rights + % to use, copy, modify, sublicense, sell, and redistribute the 4 Bitstream + % Charter (r) Type 1 outline fonts and the 4 Courier Type 1 outline fonts + % for any purpose and without restriction; provided, that this notice is + % left intact on all copies of such fonts and that Bitstream's trademark + % is acknowledged as shown below on all unmodified copies of the 4 Charter + % Type 1 fonts. + % + % BITSTREAM CHARTER is a registered trademark of Bitstream Inc. + + % The Bitstream Charter fonts have different names.... + /CharterBT-Roman (bchr.gsf) ; + /CharterBT-Italic (bchri.gsf) ; + /CharterBT-Bold (bchb.gsf) ; + /CharterBT-BoldItalic (bchbi.gsf) ; + % ... so we provide aliases. + /Charter-Roman /CharterBT-Roman ; + /Charter-Italic /CharterBT-Italic ; + /Charter-Bold /CharterBT-Bold ; + /Charter-BoldItalic /CharterBT-BoldItalic ; + % The following notice accompanied the Courier font: % *************** *** 135,142 **** % A PARTICULAR PURPOSE. ! /Courier (cour.pfa) ; ! /Courier-Italic (couri.pfa) ; ! /Courier-Bold (courb.pfa) ; ! /Courier-BoldItalic (courbi.pfa) ; % The following notice accompanied the Utopia font: --- 174,181 ---- % A PARTICULAR PURPOSE. ! /Courier (ncrr.gsf) ; ! /Courier-Italic (ncrri.gsf) ; ! /Courier-Bold (ncrb.gsf) ; ! /Courier-BoldItalic (ncrbi.gsf) ; % The following notice accompanied the Utopia font: *************** *** 160,168 **** % Utopia Bold Italic ! /Utopia-Regular (utrg.pfa) ; ! /Utopia-Italic (uti.pfa) ; ! /Utopia-Bold (utb.pfa) ; ! /Utopia-BoldItalic (utbi.pfa) ; % --- 199,215 ---- % Utopia Bold Italic ! /Utopia-Regular (putr.gsf) ; ! /Utopia-Italic (putri.gsf) ; ! /Utopia-Bold (putb.gsf) ; ! /Utopia-BoldItalic (putbi.gsf) ; ! ! % ! % ! % Shareware fonts. These have no copyright, and are of questionable quality. ! % They have their own UniqueID numbering scheme, which bears no relation ! % to that of the other Ghostscript fonts. + /Cyrillic (cyr.gsf) ; + /Cyrillic-Italic (cyri.gsf) ; % diff -rc2N gs241/LICENSE gs25/LICENSE *** gs241/LICENSE Thu Jul 4 19:02:28 1991 --- gs25/LICENSE *************** *** 1,339 **** - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 675 Mass Ave, Cambridge, MA 02139, USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your - freedom to share and change it. By contrast, the GNU General Public - License is intended to guarantee your freedom to share and change free - software--to make sure the software is free for all its users. This - General Public License applies to most of the Free Software - Foundation's software and to any other program whose authors commit to - using it. (Some other Free Software Foundation software is covered by - the GNU Library General Public License instead.) You can apply it to - your programs, too. - - When we speak of free software, we are referring to freedom, not - price. Our General Public Licenses are designed to make sure that you - have the freedom to distribute copies of free software (and charge for - this service if you wish), that you receive source code or can get it - if you want it, that you can change the software or use pieces of it - in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid - anyone to deny you these rights or to ask you to surrender the rights. - These restrictions translate to certain responsibilities for you if you - distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether - gratis or for a fee, you must give the recipients all the rights that - you have. You must make sure that they, too, receive or can get the - source code. And you must show them these terms so they know their - rights. - - We protect your rights with two steps: (1) copyright the software, and - (2) offer you this license which gives you legal permission to copy, - distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain - that everyone understands that there is no warranty for this free - software. If the software is modified by someone else and passed on, we - want its recipients to know that what they have is not the original, so - that any problems introduced by others will not reflect on the original - authors' reputations. - - Finally, any free program is threatened constantly by software - patents. We wish to avoid the danger that redistributors of a free - program will individually obtain patent licenses, in effect making the - program proprietary. To prevent this, we have made it clear that any - patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and - modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains - a notice placed by the copyright holder saying it may be distributed - under the terms of this General Public License. The "Program", below, - refers to any such program or work, and a "work based on the Program" - means either the Program or any derivative work under copyright law: - that is to say, a work containing the Program or a portion of it, - either verbatim or with modifications and/or translated into another - language. (Hereinafter, translation is included without limitation in - the term "modification".) Each licensee is addressed as "you". - - Activities other than copying, distribution and modification are not - covered by this License; they are outside its scope. The act of - running the Program is not restricted, and the output from the Program - is covered only if its contents constitute a work based on the - Program (independent of having been made by running the Program). - Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's - source code as you receive it, in any medium, provided that you - conspicuously and appropriately publish on each copy an appropriate - copyright notice and disclaimer of warranty; keep intact all the - notices that refer to this License and to the absence of any warranty; - and give any other recipients of the Program a copy of this License - along with the Program. - - You may charge a fee for the physical act of transferring a copy, and - you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion - of it, thus forming a work based on the Program, and copy and - distribute such modifications or work under the terms of Section 1 - above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - - These requirements apply to the modified work as a whole. If - identifiable sections of that work are not derived from the Program, - and can be reasonably considered independent and separate works in - themselves, then this License, and its terms, do not apply to those - sections when you distribute them as separate works. But when you - distribute the same sections as part of a whole which is a work based - on the Program, the distribution of the whole must be on the terms of - this License, whose permissions for other licensees extend to the - entire whole, and thus to each and every part regardless of who wrote it. - - Thus, it is not the intent of this section to claim rights or contest - your rights to work written entirely by you; rather, the intent is to - exercise the right to control the distribution of derivative or - collective works based on the Program. - - In addition, mere aggregation of another work not based on the Program - with the Program (or with a work based on the Program) on a volume of - a storage or distribution medium does not bring the other work under - the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, - under Section 2) in object code or executable form under the terms of - Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - - The source code for a work means the preferred form of the work for - making modifications to it. For an executable work, complete source - code means all the source code for all modules it contains, plus any - associated interface definition files, plus the scripts used to - control compilation and installation of the executable. However, as a - special exception, the source code distributed need not include - anything that is normally distributed (in either source or binary - form) with the major components (compiler, kernel, and so on) of the - operating system on which the executable runs, unless that component - itself accompanies the executable. - - If distribution of executable or object code is made by offering - access to copy from a designated place, then offering equivalent - access to copy the source code from the same place counts as - distribution of the source code, even though third parties are not - compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program - except as expressly provided under this License. Any attempt - otherwise to copy, modify, sublicense or distribute the Program is - void, and will automatically terminate your rights under this License. - However, parties who have received copies, or rights, from you under - this License will not have their licenses terminated so long as such - parties remain in full compliance. - - 5. You are not required to accept this License, since you have not - signed it. However, nothing else grants you permission to modify or - distribute the Program or its derivative works. These actions are - prohibited by law if you do not accept this License. Therefore, by - modifying or distributing the Program (or any work based on the - Program), you indicate your acceptance of this License to do so, and - all its terms and conditions for copying, distributing or modifying - the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the - Program), the recipient automatically receives a license from the - original licensor to copy, distribute or modify the Program subject to - these terms and conditions. You may not impose any further - restrictions on the recipients' exercise of the rights granted herein. - You are not responsible for enforcing compliance by third parties to - this License. - - 7. If, as a consequence of a court judgment or allegation of patent - infringement or for any other reason (not limited to patent issues), - conditions are imposed on you (whether by court order, agreement or - otherwise) that contradict the conditions of this License, they do not - excuse you from the conditions of this License. If you cannot - distribute so as to satisfy simultaneously your obligations under this - License and any other pertinent obligations, then as a consequence you - may not distribute the Program at all. For example, if a patent - license would not permit royalty-free redistribution of the Program by - all those who receive copies directly or indirectly through you, then - the only way you could satisfy both it and this License would be to - refrain entirely from distribution of the Program. - - If any portion of this section is held invalid or unenforceable under - any particular circumstance, the balance of the section is intended to - apply and the section as a whole is intended to apply in other - circumstances. - - It is not the purpose of this section to induce you to infringe any - patents or other property right claims or to contest validity of any - such claims; this section has the sole purpose of protecting the - integrity of the free software distribution system, which is - implemented by public license practices. Many people have made - generous contributions to the wide range of software distributed - through that system in reliance on consistent application of that - system; it is up to the author/donor to decide if he or she is willing - to distribute software through any other system and a licensee cannot - impose that choice. - - This section is intended to make thoroughly clear what is believed to - be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in - certain countries either by patents or by copyrighted interfaces, the - original copyright holder who places the Program under this License - may add an explicit geographical distribution limitation excluding - those countries, so that distribution is permitted only in or among - countries not thus excluded. In such case, this License incorporates - the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions - of the General Public License from time to time. Such new versions will - be similar in spirit to the present version, but may differ in detail to - address new problems or concerns. - - Each version is given a distinguishing version number. If the Program - specifies a version number of this License which applies to it and "any - later version", you have the option of following the terms and conditions - either of that version or of any later version published by the Free - Software Foundation. If the Program does not specify a version number of - this License, you may choose any version ever published by the Free Software - Foundation. - - 10. If you wish to incorporate parts of the Program into other free - programs whose distribution conditions are different, write to the author - to ask for permission. For software which is copyrighted by the Free - Software Foundation, write to the Free Software Foundation; we sometimes - make exceptions for this. Our decision will be guided by the two goals - of preserving the free status of all derivatives of our free software and - of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY - FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN - OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES - PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED - OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS - TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE - PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, - REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING - WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR - REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, - INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING - OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED - TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY - YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER - PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE - POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - Appendix: How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest - possible use to the public, the best way to achieve this is to make it - free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest - to attach them to the start of each source file to most effectively - convey the exclusion of warranty; and each file should have at least - the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) 19yy - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - Also add information on how to contact you by electronic and paper mail. - - If the program is interactive, make it output a short notice like this - when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) 19yy name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - - The hypothetical commands `show w' and `show c' should show the appropriate - parts of the General Public License. Of course, the commands you use may - be called something other than `show w' and `show c'; they could even be - mouse-clicks or menu items--whatever suits your program. - - You should also get your employer (if you work as a programmer) or your - school, if any, to sign a "copyright disclaimer" for the program, if - necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - - This General Public License does not permit incorporating your program into - proprietary programs. If your program is a subroutine library, you may - consider it more useful to permit linking proprietary applications with the - library. If this is what you want to do, use the GNU Library General - Public License instead of this License. --- 0 ---- diff -rc2N gs241/NEWS gs25/NEWS *** gs241/NEWS --- gs25/NEWS Wed Aug 19 00:55:21 1992 *************** *** 0 **** --- 1,2237 ---- + Copyright (C) 1989, 1992 Aladdin Enterprises. All rights reserved. + Distributed by Free Software Foundation, Inc. + + This file is part of Ghostscript. + + Ghostscript is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY. No author or distributor accepts responsibility + to anyone for the consequences of using it or for whether it serves any + particular purpose or works at all, unless he says so in writing. Refer + to the Ghostscript General Public License for full details. + + Everyone is granted permission to copy, modify and redistribute + Ghostscript, but only under the conditions described in the Ghostscript + General Public License. A copy of this license is supposed to have been + given to you along with Ghostscript so you can know your rights and + responsibilities. It should be in a file named COPYING. Among other + things, the copyright notice and this notice must be preserved on all + copies. + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + This file, NEWS, describes the changes in the various releases of + Ghostscript. (This file was formerly named history.doc.) + + For an overview of Ghostscript and a list of the documentation files, see + README. + + Version 2.5 (8/18/92) + =========== + + This version adds Type 1 hinting, CCITTFax encoding and decoding, and + Microsoft Windows support, as well as the usual minor improvements + and bug fixes. + + Procedures + ---------- + + Fixes bugs: + - GSIMPATH, SLZWD, and SLZWE were omitted from the VMS + makefiles, and GSIM2OUT was not removed. + - landscap.ps messed up the current path. + + Adds new switches: + -dSAFER disables file writing and directory modification. + -dESTACKPRINT causes errors to print the execution stack with + == instead of =. + -sOutputFile= replaces -sOUTPUTFILE (which is still + recognized) for setting the output file or pipe for the default + (printer) device. + -sPAPERSIZE= initializes the paper size. + -dBufferSpace= sets the buffer size for the default + (printer) device. + + For Unix systems, changes the directories in GS_LIB_DEFAULT from + `pwd` to $(gsdatadir), i.e., normally $(datadir)/ghostscript, where + datadir is normally /usr/local/lib. + + Adds a note in the header file to the effect that the X Windows + driver expects to find header files in $(XINCLUDE)/X11, not in + $(XINCLUDE). + + Changes -q so it defines QUIET as true instead of null (so it can be + used in the middle of the command line as well as at the beginning). + + Renames the history.doc file as NEWS. + + Utilities + --------- + + Platforms + --------- + + Fixes bugs: + - The stack size was not getting increased on the Watcom + platform. + + Removes "b" from the scratch file opening modes in gp_unix.c and + (conditionally) in gdevprn.c, to pacify the DECstation Ultrix system. + + Adds a makefile (bcwin.mak) and a platform file (gp_mswin.c) for + Microsoft Windows. + + On MS-DOS platforms (including Windows), uses the TEMP environment + variable to designate the directory for scratch files. + + Changes std.h so that the VMS C compiler uses function prototypes and + 'const'. + + Changes the VMS cc makefile so it doesn't use ansi2knr. + + Fonts + ----- + + Fixes bugs: + - findfont left an extra entry on the stack if it couldn't + find the default font. + + Renames bchi, ncri, and puti as bchri, ncrri, and putri, to conform + with the naming scheme for other fonts. + + Adds $(CCFLAGS) to the command line used for compiling fonts. + + Converts the .pfa fonts (CharterBT, IBM Courier, and Utopia) to .gsf, + by removing eexec encryption and also removing some mysterious + unmapped characters from Courier. This makes these fonts work with + DISKFONTS. + + Changes the implementation of compiled fonts so they are read-only + and sharable (no external references). (They are, however, not + position-independent.) + + Provides a way to use compiled fonts on platforms that limit the + number of characters in an identifier. + + Adds public-domain Cyrillic and Cyrillic-Italic fonts. + + Adds a 'userdict begin' to .loadfont, because Type 3 fonts produced + by Fontographer expect a writable dictionary on the top of the stack. + + Changes definefont for Type 1 fonts to insert UnderlinePosition and + UnderlineThickness entries in FontInfo if they are absent, because + many word processors incorrectly assume these entries are present. + + Drivers + ------- + + Fixes bugs: + - The documentation in use.doc said that the densities for + 9-pin Epson printers were 60x60 to 240x60, rather than 60x72 to + 240x72. + - gdevprn.c smashed one byte beyond the end of the string + given as the OutputFile device property. + - The X11 driver used XVisualIDFromVisual, which is not + defined in X11R3. + - The SunView driver modified the input data, which was + declared as const. + - The LaserJet IIP and III drivers shifted the page 185 + pixels to the left and 0.25" down, because the initialization string + was incorrect. + - The PCX driver wrote 16-bit values using the byte ordering + of the platform, rather than always LSB first. + - For vertical spacing, the LaserJet and DeskJet drivers used + a command that spaces N/300", rather than N scan lines, but gave it a + parameter in scan lines. + - The VESA driver didn't allocate a full 256-byte buffer for + reading the mode information from the BIOS, causing the stack to get + smashed by newer VESA implementations. + - The VESA driver didn't use the scan line length returned by + the BIOS, causing garbage output for some cards and some resolutions. + - The generic printer driver didn't free the bitmap when + closing the device, if it fit entirely in memory. + - The PaintJet driver allocated its data areas on the stack + instead of with gs_malloc. + - The generic printer driver didn't attempt to increase the + buffer size if it was too small. + - The band list driver didn't split large bitmaps properly, + leading to garbled characters at high resolutions. + - The GIF and PCX drivers used a color map that often turned + gray colors into non-grays. + + Changes the default put_props procedure so that if the device is + open, setting HWSize and/or HWResolution closes the device and + reopens it. + + Adds a driver for Microsoft Windows 3.n. + + Updates the 'cdj' and 'dj500c' DeskJet 500C drivers with new versions. + (This are user-contributed drivers.) + + Changes gdev_prn_put_props so OutputFile can be changed dynamically. + + Updates the DEC LN03 driver to also handle the LA50 and LA75. (This + is a user-contributed driver with a FSF copyright.) + + Changes the LaserJet/DeskJet driver so that -DA4 in the makefile + makes A4 paper the default. The driver now also sends an appropriate + page size selection command to the printer if the printer supports it. + + Changes all the Aladdin-supported drivers to return appropriate error + codes rather than -1. + + Adds a driver for the S3 86C911, a PC graphics accelerator used in + the popular Diamond Stealth board. This is the first driver that + uploads character bitmaps to a device; others will probably follow. + + Adds user-supplied code to the Epson driver so it will do triple + passes on 9-pin printers for higher resolution. + + Adds user-supplied code for the PaintJet XL to the PaintJet driver. + + Interpreter + ----------- + + Fixes bugs: + - zdps1.c didn't include alloc.h. + - On 32-bit systems, if maxlength of a dictionary was less + than the actual allocated space, length could become larger than + maxlength. + - flushfile didn't actually flush data when reading. + - The ASCII85Decode filter signalled EOF prematurely. + - The scanner interpreted .3D.glorp as the number 0.3, rather + than as a name. + - Closing a file freed the stream structure, creating + dangling references if there were other file objects pointing to the + same stream. + - eexec called handleerror if an error occurred, instead of + letting the error propagate to an enclosing stopped. + - gs.h made perror illegal, instead of defining it in terms + of strerror. + - One-character names weren't being allocated at + initialization, so they could be left dangling after a restore. + - Internal gsaves (i.e., the ones in show and setcachedevice) + didn't also save istate, so setfont inside a BuildChar procedure + might cause the font outside to get changed. + - The allocator incorrectly freed objects in the current + chunk that were older than the current save. + - mark was just an object, rather than an operator, so 'bind' + didn't bind it. (This is theoretically a problem for null, true, and + false also, but even more unlikely to be a problem in practice.) + - packed_get didn't cast packed integers to int, so negative + integer elements of packed arrays came out wrong. + - quit just did a gs_exit, instead of returning to the driver + in an orderly way. + - Because check_type_access checked for errors in the wrong + order, sometimes type errors were reported as access errors. + - eq didn't check for stack underflow. + - Some of the stream_procs structures weren't properly + declared const, leading to link errors on VMS. + + Implements currentcolor, currentcolorspace, setcolor, and + setcolorspace (for DeviceGray, DeviceRGB, and DeviceCMYK only). + + Implements the dictionary form of image and imagemask. All the pairs + in the Decode array must be the same; Interpolate is ignored. The + only supported color spaces are DeviceGray, DeviceRGB, and + DeviceCMYK. + + Implements files as allowable sources for the image operators. + + Removes the index field from the name structure, moving it to the + 'size' field of name refs. + + Changes the unread/sungetc operation to require that the character be + the same as the last one read from the file. + + Adds fflush calls to some debugging printout routines, because Unix + sometimes buffers terminal output. + + Implements the CCITTFaxEncode and CCITTFaxDecode filters. Implements + the general case of the SubFileDecode filter. + + Changes definefont to treat a UniqueID of 0 as equivalent to no + UniqueID, because Fontographer output apparently often violates the + specification in this way. + + Changes the default printer screen from 32.5 to 46 cells/inch. (The + old value was appropriate for a hand-rotated cell with two spots in + it.) + + Changes the utility routines to allow an integral real wherever an + integer parameter is expected in a dictionary, because Fontographer + produces fonts that violate the Adobe specification in this way. + + Adds a `dosio' feature that provides direct access to memory and to + I/O ports under MS-DOS. (This feature is not included in the + standard executables, of course.) + + Changes the default character cache limit to a 1/4" x 1/4" character + at the default resolution, rather than basing it on the preallocated + cache size. + + Removes support for t_color objects, which haven't actually been used + for several releases. + + Implements setcmykcolor and currentcmykcolor as operators, so they + will interact properly with setcolorspace and currentcolorspace. + + Changes the name of the file.h header file to files.h, to work around + a bug in the VMS header library. + + Adds command line switches @file (to treat file as more command line, + to get around the DOS 128-character command line limit) and -ffile + (so one can specify file names that begin with - or @). + + Changes the PFBDecode filter so it takes an additional boolean that + says whether or not to convert binary packets to hex. (Conversion to + hex and back to binary accounted for a substantial amount of the time + required to load .PFB fonts.) + + Splits off `copydevice' as a separate operator again. + + Library + ------- + + Fixes bugs: + - In the VMS environment, string_.h used its own prototypes + for the str... and mem... functions instead of + - gx_alloc_char_bits declared cdsize as long, but didn't + shorten it when passing it to shorten_cached_char. + - Stroking didn't suppress fattening of the lines. + - kshow didn't update the cached CTM information in the show + enumerator when returning from the callout, so further characters + could get drawn in the wrong place. + - When a memory device returned its initial matrix, it + smashed the padding fields, which contained the interpreter's type + information. + - setcachedevice didn't set the initial matrix in the cache + memory device. + - image_set_rgb (in the image operators) didn't do a + gx_color_from_rgb, so in principle one could sometimes get incorrect + colors in an image. + - The decision about whether or not to cache a character + bitmap incorrectly compared the character size against cmax rather + than cdata_size. + - show didn't reset the in_cachedevice flag in the graphics + state, so characters rendered by a recursive show were never cached. + - clip and eoclip didn't release the intermediate flattened + clip path, causing memory to be lost. + - The tile_diff routine didn't handle the case of two + identical tiles properly; this produced garbage in the band list + file. + - stringwidth didn't round the character origin to an + integral pixel; this interacted badly with hinting, causing + improperly hinted characters to wind up in the cache. + - Bitmaps (including characters) were displaced, as well as + being clipped, if they intersected the top of a clipping region. + - In gxclist and gdevmem1, the raster computation (although + not the result) could overflow an int on 16-bit machines. + + Implements decoding (sample mapping) for image and imagemask. + + Implements hinting for Type 1 fonts, based on (but not copying) the + algorithms from the X11R5 tape. + + Changes curve rasterizing to use sampling, rather than recursive + subdivision, for characters. This produces noticeably better output. + Speed penalty for non-cached characters is less than 10% at display + resolutions, up to 50% for 300 dpi printers. + + Implements gs_setcmykcolor and gs_currentcmykcolor. These are + semi-fake, since they simply convert the color to and from RGB, but + the former does set the current color space properly. + + Changes clipping regions so they use the any-part-of-pixel rule + rather than the center-of-pixel rule. This helps avoid dropouts when + using very small regions. + + Implements stroke adjustment. + + Version 2.4.2 (5/8/92) + ============= + + This is another quick release. It finally fixes rotated halftone + screens, and cleans up a few minor problems from 2.4.1. + + This release is being distributed only to beta testers and commercial + licensees, since I don't want to be distracted from working on 2.5. + + Procedures + ---------- + + Fixes bugs: + - UTRACE still appeared in the VMS makefiles. + - The support files (*.bat, *.doc, *.gsf, *.ps, Fontmap, + COPYING, README) weren't included in the MS-DOS tar file. + - The Unix install script didn't install landscap.ps. + + Replaces the type1imagepath operator with PostScript code (impath.ps, + type1ops.ps) based on the new .imagepath operator. + + Renames LICENSE as COPYING. + + Utilities + --------- + + Fixes bugs: + - pcharstr.ps had an occurrence of Subrs rather than /Subrs, + causing it to not print the Subrs, or to get an error if there were + none. + - font2c.ps didn't get the const declarations for string + dictionaries quite right. + - The missing newline at the end of gsbj.bat confused GNU + diff. + - ansi2knr would go into an infinite loop if a statement + exceeded its internal buffer size. + - Compiled fonts would get processed by ansi2knr, which + messed them up. + + Platforms + --------- + + Fixes bugs: + - Ghostscript didn't supply equivalents for rename and + gettimeofday, which some System V platforms lack. + - The missing newline at the end of gp_dosfb.c confused GNU + diff. + + Changes the Borland makefiles so that stack checking is only enabled + if DEBUG or TDEBUG is set. + + Fonts + ----- + + Changes the names of the Utopia fonts from utrg/utb/utbi/uti to + putr/putb/putbi/puti, for consistency with the rest of the font names. + Changes cour/courb/courbi/couri to ncrr/ncrb/ncrbi/ncri likewise. + + Replaces the Charter fonts with the CharterBT fonts donated by + Bitstream to the X11R5 distribution. + + Adds font aliasing capability to Fontmap. Replaces + Courier-[Bold]Oblique and ZapfChancery-MediumItalic by aliases. + + Changes the FontBBox of the Hershey fonts to be an executable, rather + than a literal, array. + + Drivers + ------- + + Fixes bugs: + - The GIF driver omitted a `private' on the definition of + gif_print_page. + - The GIF driver wrote 16-bit values using the byte ordering + of the platform, rather than always LSB first. + - George Cameron's DeskJet 500C driver had an incorrect + control sequence for skipping blank lines. + + Adds 'const' in many places, including the tile and bitmap arguments + of the tile_rectangle, copy_mono, and copy_color driver routines. + THIS IS A DRIVER INTERFACE CHANGE. (Printer drivers are not + affected, since they don't implement these routines.) + + Adds a driver for the Trident TVGA. + + Interpreter + ----------- + + Fixes bugs: + - alloc_free sometimes incorrectly chose to put an unaligned + block in an old segment on a freelist. + - The default undercolor removal function returned its + argument rather than returning 0. + + Adds NullEncode and SubFileDecode to the standard filters, since + bdftops uses the latter. + + Adds RunLengthEncode and RunLengthDecode to the optional filters. + + Removes the type1imagepath operator. (It is still available as + PostScript code, impath.ps.) Replaces it with a simpler outline + tracing operator .imagepath. + + Adds 'const' in many places. + + Makes fileposition (but not setfileposition) legal for NullEncode + filters. + + Changes the default transfer function for high-resolution devices + from the identity function to the square root function. + + Moves array_get from zgeneric.c to iutil.c. + + Changes uses of fopen to add a "b" to the access mode, rather than + relying on the _fmode global variable on MS-DOS platforms. + + Allows use of the -Z switch even when gsmain.c wasn't compiled with + -DDEBUG, since other modules might have been. + + Reorganizes gs.c and gsmain.c so that the latter can be used in + server environments. + + Replaces all uses of stdin/out/err with gs_stdin/out/err. + + Makes the number of permanent entries on the dictionary stack a + parameter, to allow inserting globaldict in the future. + + Changes BlueShift in the Type 1 font Private dictionary to allow real + numbers. (This differs from the Adobe specification, but at least + one commercial font has a real number for BlueShift.) + + Library + ------- + + Fixes bugs: + - The doubling check in init_ht (gxht.c) still sometimes + thought there was enough room to double the tile when there actually + wasn't. + - Rotated halftone screens didn't work. + - gxarith.h used #ifdef vax, rather than #if + !arch_floats_are_IEEE, to test whether IEEE floats were being used. + - pathforall didn't report a trailing moveto. + + Replaces gs_type1imagepath with gs_imagepath. + + Allows sOUTPUTFILE=-, meaning output to stdout. + + Adds 'const' in many places. + + Replaces all uses of stdin/out/err with gs_stdin/out/err. + + Version 2.4.1 (4/21/92) + ============= + + This is a quick release to fix minor problems discovered in 2.4, and + to add a few improvements that didn't quite make it into 2.4. It + also adds GIF and PCX file support. + + Procedures + ---------- + + Fixes bugs: + - Some makefile dependencies, and the ccgs script, caused trouble + for parallel versions of `make'. + - Compiling genarch with -O with gcc on the RS/6000 produced a + buggy executable. + + Fixes some minor problems in make.doc. + + Adds DEVICE_DEVS2..5 to handle long device lists. + + Removes the need to set GS_RUN_EXE when using the Watcom compiler on + MS-DOS systems. + + Gets rid of gs_ccfnt.ps, merging its function into gs_fonts.ps. + + Gets rid of gconfig.ps; this information is now compiled in gconfig.c. + + Utilities + --------- + + Fixes bugs: + - The palette for pstoppm in 8-bit mode didn't contain all 8 + primary colors. + - font2c used just values_ to mean &values_[0]; some compilers + couldn't handle this. + + Makes font2c insert `const' in many appropriate places. + + Drivers + ------- + + Fixes bugs: + - The SunView driver had not been updated properly for 2.4 and was + pretty thoroughly broken. + - None of the printer drivers worked properly with the Watcom + compiler, because stdprn was doing \n -> \r\n substitution. + - If the generic printer driver couldn't allocate the requested + size command list buffer, it gave up rather than trying to allocate a + smaller buffer. + - The SuperVGA drivers (except for the VESA driver) didn't + work with the Watcom compiler, because a couple of places in the + drivers weren't truncating the offset of "segmented" pointers + properly. + - Some of the H-P used *b#Y rather than *p+#Y for + vertical positioning; this apparently is wrong, at least for the + LJIIp. + + Removes the dependence of the X Windows driver on Xt, Xext, and Xmu. As a + result, Ghostscript will not install a standard colormap itself, but it + will use one if one is already installed. + + Adds a set of drivers for Portable Bitmap, Graymap, and Pixmap file + formats. + + Adds drivers for monochrome, EGA/VGA-style, and SuperVGA-style PCX + file formats. + + Adds drivers for monochrome and 256-color GIF file formats. + + Fonts + ----- + + Adds ZapfChancery-MediumItalic as a copy of ZapfChancery-Oblique. + + Interpreter + ----------- + + Fixes bugs: + - A value with l_new set could 'escape' to save level 0 on a + stack; if stored, it prevented the slot from being saved and restored + properly. + - 16#7fffffff + 1 gave the floating point equivalent of -2^31, not + 2^31. + - The PFBDecode filter computed the packet length incorrectly if + the 0x8000-bit of the length was set. + - 5-byte numbers in Type 1 CharStrings complained of a rangecheck + if they exceeded 16 bits, rather than if they exceeded the integer part of + a fixed. + - (, ), and \ appearing in file name arguments in the command + line did not work properly. + + Adds 'const' in many places. + + Changes the random number generator to be the same as the one used in + Level 2 PostScript (as reported by Ed Taft on comp.lang.postscript). + + Exits with code 1 rather than code 0 on an unrecoverable error detected at + the PostScript level. + + Makes dictionaries expand automatically when they fill up. + + Adds gp_exit to complement gp_init. + + Changes dictionaries to always allocate a power of 2 entries on + 32-bit machines. Changes the name table to allocate indices + scattered, so dictionary lookup doesn't have to do a multiply to + scramble the index. + + Changes the handling of currentfile to do "shallow binding" so stack + searching is almost never required. + + Library + ------- + + Fixes bugs: + - arc and arcn got a numeric exception if the radius was zero. + - The undocumented 15 opcode in Type 1 fonts wasn't ignored. + - PaintType 3 wasn't allowed. (It isn't clear what it should + mean; we treat it as equivalent to 0.) + - The VAX/VMS C compiler was generating incorrect code for the + chi_bits and cmask macros in gdevmem, producing incorrect output. + - If the result of the slow algorithm for intersecting clipping + paths was a rectangle, the wrong thing happened (cbox didn't get set). + - gx_path_is_rectangle didn't recognize open rectangles. + - clist_change_tile didn't check properly whether the tile + size had changed, so changing the screen could produce invalid band + files. + - The image operators did the wrong thing in the 1-for-1 + case, interleaving N bytes of data with 7*N bytes of garbage. + - stroke sometimes handled bevel and miter joins wrong in + reflected coordinate systems. + - init_ht checked incorrectly whether there was enough room + to Y-replicate tiles, so sometimes it did it when it shouldn't have. + - stroke sometimes thought lines were thin when they weren't. + + Adds 'const' in many places. + + Adds support for 2- and 4-bit-per-pixel memory devices. + + Version 2.4 (3/25/92) + =========== + + This is a major release that adds SuperVGA support, support for Metrics, + settable device properties, and incremental font loading. It also + includes important performance improvements, based on rewrites of some key + algorithms, and quite a few new Level 2 / Display PostScript facilities. + + Procedures + ---------- + + Fixes bugs: + - The rule for compiling gconfig.c didn't include the -I switches. + - .bat files were being distributed with a \n line terminator + rather than \r\n. + - A CLOSE MODULE_LIST was needed after END_COMPILE: in the VMS + command files. + - Unix systems couldn't handle multiple drivers with overlapping + sets of files. + - -s defined as a null, rather than as an empty string. + + Adds gconfig.ps to the list of needed configuration files. + + Changes the way that the makefile handles nested .h files, so that it + doesn't have to `touch' them. + + Adds the loadallfonts procedure to gs_fonts.ps. + + Changes the standard DOS configuration to include VGA, EGA, VESA, Epson, + BubbleJet, and H-P printer drivers. + + Renames ghost.mak as gs.mak, and gdevs.mak as devs.mak. + + Adds a USE_ASM flag so that one can build a DOS version of Ghostscript + without having an assembler. + + Splits off common code from the two MS-DOS makefiles into tccommon.mak. + + Replaces the COPYING and LICENSE files with a new LICENSE file containing + version 2 of the GNU General Public License. + + Removes DEVICES and DEVICE_OBJS from the makefiles, since they are no + longer needed. + + Adds a GS_DEVICE environment variable to supply a default device name if + desired. + + Adds ansihead.mak and unix-ansi.mak, to parallel [g]cc-head.mak and + unix-[g]cc.mak, for other ANSI C compilers. + + Changes the way that optional features are defined in the makefiles, so + that they actually work. + + Adds support for the Watcom C/386 compiler. + + Allows # in the command line as equivalent to =, to compensate for + brain-damaged MS-DOS shell. + + Adds -sOUTPUTFILE= to set the output file or pipe. + + Adds -dWRITESYSTEMDICT to leave systemdict writable. + + Utilities + --------- + + Fixes bugs: + - pcharstr.ps insisted on having Subrs be present in the font. + - pcharstr.ps decoded negative numbers between -108 and -1131 + incorrectly. + - pfbtogs.ps didn't handle packets longer than 64K correctly. + + Changes the bdftops utility so that it makes entries for UnderlinePosition + and UnderlineThickness in FontInfo, and so that it always records a + FullName (the FontName if no other is provided). + + Changes the name of the pfbtops utility to pfbtogs, because groff already + includes a program called pfbtops. + + Adds the gslp utility for doing "line printing" of text files, similar to + enscript + lpr. + + Adds a new variable DITHERPPI that enables a different dither pattern, + claimed to be better for printers. + + Adds the font2c utility for compiling Type 1 fonts into C, so they can be + linked into an executable rather than loaded dynamically. + + Drivers + ------- + + Fixes bugs: + - gdev_prn_copy_scan_lines was erroneously masking the last byte + of data even on color printers, as was paintjet_print_page. + - The TruFax driver had a couple of compilation errors, since it + hadn't been compiled in a while. + - The BGI driver sometimes didn't consult BGIPATH when looking for + .BGI files. + - initclip did the wrong thing with memory devices. + - The BGI driver didn't look in BGIDIR for .BGI files. + - The Epson driver didn't set the right margin properly with + ESC+Q. + - The BJ-10e driver was badly broken. + - gdev_prn_open/close_printer didn't reset the command list file, + so it was taking quadratic time to print multi-page documents. + + Adds color to the SunView driver. + + Adds selectable resolution (75, 100, 150, or 300 DPI) to the + DeskJet/LaserJet driver. + + Changes gssetdev so that drivers can specify special libraries to be + loaded, as well as object files. + + Adds a driver for VESA-compliant SuperVGA displays. This driver handles + all resolutions from 640 x 400 up to 1280 x 1024, in 256-color mode. The + default is VGA resolution (640 x 480). + + Adds a driver for the ATI Wonder SuperVGA card, and for SuperVGA cards + using the Tseng Labs ET3000 or ET4000 chip such as the STB VGA EM-16 and + the Orchid ProDesigner II (256-color modes only). + + Adds a driver for Trident and Tseng Labs SuperVGA cards in 800 x 600, + 16-color modes (for cards with only 256K of memory). + + Adds user-contributed drivers for the Ricoh 4081, DEC LN03, Canon LBP-8II, + and H-P DeskJet 500C printers. + + Adds Tim Theisen's Ghostview changes to the X11 driver. + + MAKES NON-BACKWARD-COMPATIBLE CHANGES TO THE DRIVER PROCEDURE INTERFACE as + follows: + + - Changes map_rgb_color and map_color_rgb to always work in a + 16-bit color value space, rather than a space defined by the + maximum number of distinct colors provided by the device. + + - Adds an argument to the output_page procedure to indicate + whether the procedure is being called for copypage or + showpage, and a num_copies argument. + + - Adds a gx_bitmap_id to the copy_ and tile_ procedures, so that + drivers can cache bitmaps in the server or device if they want + to. + + - Removes fill_trapezoid and tile_trapezoid. + + - Adds a new get_bits procedure for reading the bits back from the + driver buffer (when possible), replacing copy_scan_lines. + This procedure takes a new argument describing padding and + byte swapping, and returns a different value from + copy_scan_lines. + + - Adds get_props and put_props procedures for accessing arbitrary + additional properties of devices. The interface is quite + complex, but provides a great deal of flexibility. + + See drivers.doc for details. + + Changes gdev_mem_bytes_per_scan_line to gdev_prn_bytes_per_scan_line. + + Adds a user-contributed driver for DigiBoard, Inc.'s fax software. + + Fonts + ----- + + Changes Type1BuildChar so it uses the information from the Metrics + dictionary in the font, if Metrics is present. + + Changes findfont (.loadfont) so it recognizes .PFB fonts and can load them + directly. Also changes .loadfont to disable packing temporarily, because + some fonts rely on procedures being writable (!). + + Interpreter + ----------- + + Fixes bugs: + - The hypot function is not available on some Unix systems. + - Ghostscript didn't flush and close files when exiting. + - In statusdict, the /margins procedure used .leftmargin, but + /setmargins used .lmargin. + - An out-of-range putinterval would simply do nothing, rather than + reporting an error. + - If an attempt to allocate a block larger than the allocator's + chunk size (20K) failed, the allocator would erroneously think it had + succeeded. + - The bind operator made the top-level procedure read-only, as + well as interior procedures. + - gs.c copied 1 extra character for the value of strings defined + on the command line with -s...=, which could smash the first byte of the + next object in memory. + - copying a dictionary erroneously required the maxlength of the + destination to be greater than or equal to the maxlength of the source, + rather than the length of the source. + - undef didn't correctly decide when to mark a deleted entry as + deleted vs. free; as a result, some keys couldn't be looked up properly + after an undef. + - type1encrypt and type1decrypt didn't set the size of the result + properly. + - cvi and cvr didn't allow leading or trailing whitespace in + strings. + - cvs didn't cause an error if the destination string was too + short. + - Many operators didn't check correctly for stack underflow (off + by 1). + - `for' used reals, rather than integers, if the limit was a real, + even if the initial value and increment were integers. + - `restore' didn't properly invalidate copies of the save object + being restored from; `save dup restore restore' would crash. + - `restore' sometimes didn't undo stores into matrices that were + stored into by operators. (The identity matrix always had l_new set.) + - readline gave a rangecheck if the input line exactly filled the + string. + - `--' as the last switch on the command line caused a crash + rather than an error message. + - On MS-DOS systems, filenameforall didn't handle patterns with a + drive or directory specifier properly. + - stroke sometimes called gz_draw_line_fixed even if the line went + outside the clipping box by 1 pixel. + + Changes the loop that binds procedure "operators" to entirely disable the + handling of the typecheck error, rather than to use stopped. This cuts + initialization time significantly, and also eliminates about 35K of wasted + space (for saving the stacks). + + Changes the version "operator" so it returns 47.0. Adds "revision" to + define the Ghostscript version # x 100. + + Adds gscurrentresolution and gssetresolution procedures for getting and + setting the device resolution. + + Adds -r and -rx as command line options for setting + device resolution. + + Adds a facility for incrementally loading the individual CharStrings of a + Ghostscript font from the disk. This can save a lot of memory, at the + expense of slower rendering. (It is intended primarily for MS-DOS + systems.) + + Changes findlibfile to return the name of the file that was actually + opened, as well as the file itself, when the operation succeeds. + + Changes the name of the main entry to the interpreter from interpret to + gs_interpret, because of a conflict with a Data General library procedure. + + Adds the .setmetrics operator to set the metrics for the current + character for Type 1 fonts. + + Adds more LaserWriter-specific entries to statusdict. + + Gives names to all the internal `operators', so they will print out + reasonably when an error occurs. + + Extends the status operator to accept a string and return file + information, as defined for Level 2 PostScript. + + Adds the filter operator and some specific filters: ASCII85Encode, + ASCII85Decode, ASCIIHexEncode, ASCIIHexDecode, eexecDecode, NullEncode, + PFBDecode, and the null case of SubFileDecode. + + Extends the scanner to recognize the Level 2 << and >> tokens. + + Adds a facility for extracting the text strings from a PostScript file and + writing them out in a simple format (selected by -dASCIIOUT, implemented + by gs_2asc.ps). + + Implements all of the remaining Display PostScript facilities that are + also in Level 2 (i.e., everything in section A.1.3 of the PostScript + Language Reference Manual, Second Edition, that is not also in section + A.1.2). The virtual memory operations are all stubs; the new halftone + options are not fully implemented. + + Changes makeimagedevice to use a string of gray or RGB values, rather than + an array of color objects, to specify the palette. Removes + currentgscolor and setgscolor from the interpreter, but leaves t_color + objects in, since they may be useful later. + + Adds getdeviceprops and putdeviceprops for manipulating device properties. + Currently defined properties for all devices: InitialMatrix, HWResolution, + HWSize, Name. Currently defined properties for printers: BufferSpace, + MaxBitmap, OutputFile. OutputFile allows |command for piping on Unix + systems. + + Removes deviceparams and makedevice. Adds devicedefaultmatrix. + + Implements reversepath. + + Makes copy work on devices. + + MS-DOS specific + - - - - - - - - + + Fixes bugs: + - iutilasm.asm wouldn't assemble with newer versions of MASM if + CPU_TYPE was set to 286 or above. + - CPU_TYPE=386 didn't properly substitute the faster + multiply/divide routines under Turbo C++ or Borland C++, only under the + original Turbo C. + + Library + ------- + + Fixes bugs: + - A curve whose first and last points were the same wouldn't get + drawn at all. + - A bug in the Turbo C++ compiler generated bad code when shifting + a long right by 1 bit. + - If stroking a dashed line ever encountered a segment that was + completely blank, Ghostscript would indirect through a null pointer. + - arc and arcn gave an error if the radius was negative. + - stroke always used the general algorithm, even if the line was + guaranteed to be thin. + - arc and arcn erroneously reduced the angles mod 360. + - Very large or negative 32-bit numbers in Type 1 fonts didn't + work properly on MS-DOS systems (the ff0000 bits got set to zero). + - Color printer devices rendering entirely in memory only + allocated a monochrome-sized bitmap. + - clip and eoclip didn't intersect the paths properly in the + general case. + - charpath erroneously rounded the current point to an integral + value, causing characters to be spaced improperly. + - The definition of max_color_param got some compilers confused. + - charpath always used quadratic time and space, and dropped all + but the last character when used with a Type 3 font. + - Stroking a path with a 180 degree angle would incorrectly miter + instead of beveling. + - Type 1 fonts used the current flatness for curves, which could + produce bad (and inconsistent) results. + - Stroking a degenerate line segment produced incorrect results. + + Changes the character cache to use the UniqueID as the key, when + available, instead of the font pointer. This dramatically improves + performance when fonts are getting removed and reloaded because of page + isolation with save/restore. + + Removes some unnecessary casts to (float) from gsmatrix.c and gscoord.c. + + Changes the Type 1 interpreter so that it rounds line and curve endpoints + to the center of the nearest half-pixel, and omits null line segments. + This both speeds up rendering at small sizes and improves output quality. + + Changes gs_deviceparams to return resolution as well as extent; changes + gs_makedevice to accept resolution as well as extent. + + Replaces the algorithm for approximating circular arcs with curves with a + more accurate one. + + Changes gs_point and gs_rect to use doubles rather than floats. + + Adds gs_setmetrics, for overriding Type 1 font metrics for the current + character. + + Changes clipping to use lists of rectangles rather than path intersection. + This makes a big difference when clipping bitmaps (including characters). + + Changes the character cache to discard entries incrementally, rather than + clearing the entire cache when it fills up. + + Changes the implementation of transfer functions to use a cached map, + built when the transfer function is set. This makes transfer functions + work properly in all situations, including images. + + Defines a .quit operator that takes an exit code, and redefines quit in + terms of it. + + Adds support for 16-bit-per-pixel devices in gdevmem. + + Adds gs_copydevice and gs_deviceinitialmatrix; removes gs_deviceparams and + gs_makedevice. + + Changes setscreen to ensure that the cell is always at least 4x4 pixels in + size. + + Version 2.3 (8/28/91) + =========== + + This is a minor release to fix two bugs and add the PaintJet driver, which + didn't make it into 2.2. + + Utilities + --------- + + Changes the pstoppm utility so it counts pages correctly even in the + presence of arbitrary saves and restores. + + Drivers + ------- + + Adds a new, "supported" PaintJet driver. + + Changes the Epson driver to use ESC+D rather than ESC+\ for horizontal + positioning, since many printers don't support the latter. + + Adds horizontal double-density (two-pass) printing to the Epson driver, so + it can do 240 x 60 and 360 x 180 densities. (Vertical double density is + not supported yet.) + + Version 2.2 (6/1/91) + =========== + + The purpose of this release is to add save/restore, and a few + miscellaneous Level 2 P*stScr*pt features such as undef. It also includes + major improvements in graphics quality and in handling of high-resolution + printers. + + Procedures + ---------- + + Changes the version numbering to M.mpp rather than M.m.p, so that + `version' can be a real number for those programs that insist on it. + + Renames ghost.ps as gs_init.ps, gfonts.ps as gs_fonts.ps, and statusd.ps + as gs_statd.ps. The initialization files now all are named gs_*.ps. + + Renames gdevs.{c,h,tl} as gconfig.{c,h,tl}. + + Changes the relevant makefiles and command files so that a single build + can contain several drivers that share code, e.g., the Epson driver and + the DeskJet driver. + + Changes gs_init.ps so it relies on an external gconfig.ps file rather than + making a specific test for the presence of Level 2 features. + + Adds an entry for uglyr.gsf to the makefile. + + Removes the distinction between CCA and CCNA, since most of the files now + contain constructs that require non-ANSI compilation on MS-DOS platforms. + + Adds a `man' page for the ansi2knr utility. + + Changes the documentation (use.doc) to show how to use -sDEVICE=, + or the selectdevice procedure, to select devices by name. + + Adds DEVICE_DEVS to the makefiles (analogous to DEVICES and DEVICE_OBJS). + This finally makes the make procedure fully automatic. + + Adds the name of the initialization file (gs_init.ps) as a + platform-specific makefile parameter, GS_INIT. + + Removes the test program gt.{c,tr} from the fileset, since it is not + useful to users. + + Moves the Symbol encoding vector to a separate file (symbol_e.ps), from + which it is loaded when first used. + + Changes the error handler so it can handle errors that occur while reading + the initialization files. + + Extends ansi2knr so it can handle `void' and `...' in parameter lists. + + Adds quit.ps to the set of installed files. + + MS-DOS-specific changes + - - - - - - - - - - - - + + Adds the VGA and BGI drivers to the standard MS-DOS configuration, and + makes VGA the default. + + Adds a `+' and a newline at the end of gs.tr, to avoid problems with file + transfer programs or editors that add a newline at the end of files. + + Changes the name of msdos.mak to turboc.mak, and creates a new tbcplus.mak + makefile for use with Turbo C++ and Borland C++. + + Changes the extension of the loader response files from .tl to .tr. + + Changes the default search path from c:/ghost and c:/ghost/fonts to c:/gs + and c:/gs/fonts. + + Changes the directory separator from `|' back to ';', since it appears + that DOS can handle a ; in a command line if it is prefixed with \. + + Unix-specific changes + - - - - - - - - - - - + + Changes the uses of install in unixtail.mak so they only install a single + file at a time, which is all that the standard Unix install allows. + + Removes the duplicate files (README/readme, LICENSE/license, + COPYING/copying, Fontmap/fontmap). + + Changes the ld flags from LDPLAT to LDFLAGS. + + Adds XCFLAGS and XLDFLAGS. These are concatenated with CFLAGS and LDFLAGS + respectively. The intention is that they be set from the `make' command + line if desired. + + VMS-specific changes + - - - - - - - - - - + + Repairs the omission of ZPACKED from the VMS build lists. + + Drivers + ------- + + Fixes bugs: + - The SunView driver produced semi-garbage on little-endian + platforms (Sun-386i) because it didn't swap the bit order. + - The X driver would dump core if it couldn't open the display and + the DISPLAY environment variable wasn't set. + - The X driver relied on white = 0, black = ones in a couple of + places; + - The X driver would return an error, instead of clipping, if + asked to display outside the window. + - The X driver would create inappropriately sized windows, because + it believed the server's report of the screen resolution. + + Adds Fran Taylor's Private Eye driver to gdevs.mak and the fileset (not + supported by Aladdin Enterprises). + + Adds Neil Ostroff's TruFax driver to gdevs.mak and the fileset (not + supported by Aladdin Enterprises). + + Makes the scratch file template for the printer drivers a per-platform + quantity (gp_scratch_file_name_template). Puts the default scratch files + for Unix in /usr/tmp rather than /tmp. + + Changes the SunView driver to prevent the Ghostscript window from being + destroyed (which badly confuses the interpreter). + + Extends the Epson driver to handle a variety of print densities in both X + and Y, to handle 24-pin as well as 8-pin graphics, and to allow optional + specification of default density in the makefile (gdevs.mak). + + Refactors the printer drivers so that a single driver handles both DeskJet + and LaserJet. Adds LaserJet drivers that use the new compression modes on + the LJ IId/IIp and LJ III. + + Changes all the printer drivers to use band lists rather than bitmap + paging as the buffering method. (The individual drivers need only a + one-line change to replace mem_copy_scan_lines with + gdev_prn_copy_scan_lines with a different argument.) + + Adds the halftone phase as additional arguments to tile_rectangle and + tile_trapezoid. + + Adds an entirely new and much simpler PaintJet driver, using the new band + list interface. + + Adds margin information to the device structure. This is currently only + relevant for printer devices. + + Adds BGIPATH and BGIUSER environment variables, allowing additional + control of the BGI driver. + + Changes the x/y_pixels_per_inch member of the device structure from int to + float. + + Fonts + ----- + + Patches gs_fonts.ps so definefont will add an isFixedPitch entry to + FontInfo if there isn't one there. + + Removes the old "type 7 path" encoding code from gs_fonts.ps. + + Changes bdftops so it puts isFixedWidth and ItalicAngle entries in the + FontInfo dictionary of the fonts it creates, since some P*stScr*pt + programs rely on this. + + Changes bdftops so it synthesizes as many missing characters as possible + out of the ones that are there (in particular: synthesizes accents out of + punctuation marks, and accented characters using seac.) The results + aren't all that good, but they're a lot better than having characters + missing out of the font. + + Utilities + --------- + + Adds a pfbtops utility for converting .PFB fonts to standard Ghostscript + fonts. + + Fixes bugs: + - ps2image didn't reset things properly between pages for + multi-page documents. + + Interpreter + ----------- + + Makes Ghostscript recognize `-' alone as meaning that it should read from + standard input as though it were a file. This allows Ghostscript to + accept a pipe as input. + + Fixes bugs: + - seac in type1addpath used the current font's encoding, not + StandardEncoding. + - type1decryptfile (eexec) didn't recognize binary (as opposed to + hex) representation. + - Mentioning a name whose value was a no-access object caused an + invalidaccess error. + - There was a bogus definition of `run' in zfile.c. + - The interpreter didn't handle end-of-file on stdin properly. + - Real numbers with an 'e' or 'E' but no decimal point were not + recognized. + - On MS-DOS systems, inside strings, \ followed by a newline was + not discarded properly. + - On MS-DOS systems, the long unsigned divide routine sometimes + gave incorrect answers. Among other things, this caused alternate-radix + numbers sometimes to crash the interpreter. + - cvrs didn't do the right thing about reals or negative integers. + - .echo.mode was being reset with def instead of store, and was + defined in systemdict rather than userdict. + - setgray and settransfer didn't interact properly. + - 16#80000000 was being interpreted as a signed integer (and + converted to a real) rather than an unsigned one. + - atan returned 0 sometimes when it should have returned 180. + - currentcmykcolor was defined wrong. + + Removes the filename operator, since no standard Ghostscript code used it, + and it caused problems with some P*stScr*pt files. + + Implements new operators: filenameforall, selectfont (as a procedure), + stringmatch, undef. + + Adds new standard procedures: selectdevice. + + For MS-DOS, requires that the operand and execution stacks be located in + the data segment, and uses short pointers to address them. This produces + significantly smaller and faster code. (These changes are not visible to + users or library clients.) + + Changes the assignment of attribute bits, and adds new bits for + save/restore and the garbage collector. Changes many of the macros in + store.h to support save/restore. (These changes are not visible to users + or library clients.) Implements save and restore. + + Moves type names from gs_init.ps to ghost.h and ztype.c. + + Moves error names from gs_init.ps to errors.h and iinit.c. + + Introduces gp.h as a documented interface to the platform-specific files. + + Adds the -- switch, which allows Ghostscript programs to take arguments + from the command line. + + Changes many uses of the name `name' to something else, to avoid upsetting + the Microsoft C compiler. + + Really implements packed arrays -- they took the same amount of space as + ordinary arrays in previous versions. + + Changes exitserver in serverdict so that it just clears the stacks. (This + isn't the correct fix, but it will do as a workaround.) + + Makes many miscellaneous small changes to pacify various compilers. + + Changes gs_fonts.ps so that when "quiet" mode is selected (-q switch), + Ghostscript doesn't print anything when loading fonts or when substituting + for undefined characters. + + Defines the name consisting of just a control-D as a no-op, because some + P*stScr*pt-generating applications put control-Ds in their output. + + Implements halftone phase (sethalftonephase and currenthalftonephase + operators). + + Removes the -E switch, since it is no longer useful. + + Changes the -w and -h switches to a single -g (geometry) switch, with + usage -gx. Makes the -h switch, and a new -? switch, print + usage help. + + Implements correct handling of stack overflow errors (makes an array out + of the contents of the overflowing stack, and resets the stack, before + invoking the error handler). + + Adds t_oparray (`operators' defined as procedures) and the makeoperator + operator. This is so that programs like the Distillery that rely on all + operators being bound by `bind' will work properly. + + Adds a new NOPAUSE flag to suppress the prompt and pause at copypage and + showpage. + + Library + ------- + + Fixes bugs: + - gs_type1_interpret didn't store the encryption state or the skip + count before returning to let the client handle a seac or an endchar in + the middle of a seac. + - The definition of the Type 1 operator ce_testadd was based on + wrong information; the operator takes only 2 operands and does something + unknown. + - mem_true24_copy_mono wasn't incrementing the destination pointer + if the color was transparent, leading to garbled characters. + - gx_lookup_fm_pair would sometimes look at one entry beyond the + end of the cached font/matrix pair area. (This probably had no practical + effect.) + - gs_type1_interpret didn't save the current point when returning + to the client for a callothersubr, causing some characters to be rendered + displaced (such as some of the chess pieces in chess.ps). + - gs_setgray, gs_sethsbcolor, gs_setrgbcolor, gs_setflat, and + gs_setlinewidth gave errors for out-of-range operands rather than forcing + them into range. + - Transfer functions were not actually supported. + - The area fill algorithm failed on certain complex paths. + - The current point was sometimes defined when a BuildChar + procedure was called. + - Stroking a degenerate line didn't display anything for round + caps or joins. + - If the ends of a curve had exactly the same X coordinate, the + curve sometimes wouldn't be displayed. + - Very thin lines that went outside the clipping region would + sometimes be displayed as dashed, or not at all. + - The translation in a FontMatrix was ignored. + - Very wide, shallow lines would color extraneous pixels when + using bevel or miter joins. + - Dashed lines didn't join properly at the beginning of a closed + path. + - 0-degree arcs didn't add the appropriate line (possibly + degenerate) to the path. + - gs_type1_interpret didn't reset the callsubr stack when starting + the base character of a seac, which caused confusion if the accent's + endchar fell inside a Subr. + - Non-monochrome memory memory devices weren't checking the + arguments of the drawing procedures properly. + - The initial clipping rectangle for memory devices was being + computed wrong. + - Null devices had a semi-infinite clipping rectangle instead of + an empty one. + - gs_setlinewidth was treating negative arguments as zero, instead + of taking the absolute value. + - imagemask with a dithered color used a solid color rather than + the dithered one. + + Tweaks the area fill and image rendering algorithms to be a little more + liberal with paint when being used to render characters. + + Changes the name of the 8-bit mapped color memory device from + mem_mapped_color_device to mem_mapped8_color_device. + + Changes the memory devices so that on little-endian platforms, they can + store the bytes within a word in either order. (Little-endian order + allows efficient 32-bit updating, big-endian is required when displaying + or writing to a printer or a file.) + + Implements halftone phase. + + Replaces the trapezoid fill algorithm with a much more accurate one + inspired by a contribution from Paul Haeberli. This also changes the + graphics convention back to filling only pixels whose center falls within + the region to be filled. + + Changes the character cache to allocate headers and bits contiguously out + of a single ring buffer. + + Changes gs_imagemask and gs_imagemask_init to take a thickness adjustment + parameter. + + Changes gs_setcachedevice and gs_setcharwidth to take the graphics state + as a parameter. + + Renames gx_device_memory_bitmap_size as gdev_mem_bitmap_size, + mem_copy_scan_lines as gdev_mem_copy_scan_lines, and + mem_bytes_per_scan_line as gdev_mem_bytes_per_scan_line. + + Version 2.1.1 (1/15/91) + ============= + + This is a sub-release distributed to fix a few early bugs in 2.1, just in + time for the new GNU master tape. + + Build procedures + ---------------- + + Removes all of the (undebugged) Level 2 code from the fileset, as well as + the (unused) file gdevvga.c. + + Changes the tar file so that the files are stored in the directory + gs rather than simply gs, e.g., gs211. + + Interpreter + ----------- + + Changes the scanner so that \ is recognized within strings regardless of + whether the scanner is reading from a string or from a file. This is + compatible with newer P*stScr*pt interpreters, and with the newer + P*stSc*pt language specification, but not with the older specification in + the original PostScript Language Reference Manual. + + Drivers + ------- + + Fixes the max_value macro in gdevmem.c so that compilers won't complain + about a left shift by 32. + + Adds 'byte' to the list of types that gdevx.c must sidestep because header + files use them. + + Library + ------- + + Changes the computation of penum->unpack in gsimage.c so as not to upset + compilers that don't treat procedures and pointers to procedures as + compatible types for conditional expressions. + + Version 2.1 (12/31/90) + =========== + + This is primarily a bug fix release to clean up problems in 2.0. It also + implements a first cut at the new color operators. + + Build procedures + ---------------- + + Changes the separator for multiple directories in MS-DOS from ';' to '|', + since there is no way to include a ';' in a command line. + + Adds /fonts to the default search path, where is c:/ghost for + MS-DOS systems and `pwd` for Unix systems. + + Adds new documentation describing how to direct output to the printer. + + Changes the PROCTYPE and USE8087 options in MSDOS.MAK to CPU_TYPE and + FPU_TYPE. The latter now indicates the type of FPU to generate code for, + if any. + + Drivers + ------- + + Adds a driver for the Canon BubbleJet BJ10e. + + Modifies the EGA driver to handle (non-standard) frame buffers larger than + 64K. Adds drivers for the VGA and for the EIZO MDB-10 (a 1024 x 768 frame + buffer). + + Changes the X driver so that it clips to the window dimensions, rather + than reporting an error. + + Notes that the H-P LaserJet driver, like the DeskJet driver, works under + Unix as well as MS-DOS. + + Adds support for 120 X DPI mode, and for the LQ-1500, to the Epson driver. + + Fonts + ----- + + Fixes bugs in bdftops: + - It was using /UniqueId instead of /UniqueID as the key for the + font unique ID. This effectively disabled the font cache. + - The definition for .notdef was bogus -- an invalid CharString. + + Changes ghost.ps and gfonts.ps so that NullFont is the initial font, + rather than Ugly. + + Arranges things so that when attempting a font substitution, if the + default font is not found, NullFont is used instead. + + Extends bdftops so that if certain easily synthesized characters are + missing from a font, it will attempt to synthesize them using available + characters. + + Interpreter + ----------- + + Extends the -T switch to allow specifying a printf template for the + arguments of the procedure being traced. + + Fixes bugs: + - /0 was interpreted as equivalent to 0 (a number) rather than a + literal name. + - packedarray was defined as being like array, instead of like + array followed by astore. + - Many minor and harmless type mismatches (and a couple of very + minor genuine bugs) were upsetting the Apollo C compiler. + - exp was incorrectly failing in certain cases with a negative + first argument. + - copyscanlines incorrectly required at least 4 elements on the + operand stack, although it correctly only used the top 3. + - readhexstring incorrectly read 1 byte even if the string length + was zero. + - Not every place that expected an array would accept a packed + array. + - Very complex paths (and infrequently other things) could produce + a 'memory leak'. + - / alone would skip following whitespace and gather following + characters, rather than creating an empty name. + - ghost.ps left newerror defined as true in $error, which resulted + in an erroneous error report if a program executed a 'stop'. + - The definition of exitserver in serverdict didn't clear the + stack. + - currentfile returned an executable file, rather than a literal + one. + - setfont for Type 1 fonts didn't check the UniqueID in the font + dictionary against the one in the font's Private dictionary. + - A value stored in a dictionary under the key /xxx couldn't be + retrieved using the key (xxx), and vice versa. + - charpath with a Type 1 font on a string containing a 'space' + would produce garbage (it released the parent path inappropriately). + - bytesavailable did not work properly for terminal input. + + Changes the interface to the memory allocator so that it always takes an + element size and an element count, like calloc instead of malloc (but note + that alloc does *not* clear just-allocated blocks). Gets rid of the + special 'dynamic' allocation procedures. + + Changes the random number operators to use a better implementation. + + Changes the idiv operator so it will accept any numbers, not just + integers, as arguments. (The PostScript manual doesn't allow this, but + implementations apparently do.) + + Provides semi-fake but usable definitions for all of the color PostScript + extensions, including a real implementation of colorimage. + + No longer uses the name 'null', which is apparently reserved by Microsoft + C. Makes a number of other minor changes required to pacify the Microsoft + C compiler. + + Implements %statementedit and %lineedit. (%statementedit is equivalent to + %lineedit, which is wrong.) Changes the interactive interpreter to use + %statementedit. + + Changes the scanner to accept null, ctrl-K (vertical tab), and ctrl-L + (form feed) as whitespace. Ctrl-L terminates a comment, null and ctrl-K + do not. + + Allows a literal string as the 'proc' argument(s) for image, imagemask, + and colorimage. + + Adds the following operators/procedures: arct, cleardictstack, deletefile, + renamefile. + + Defines =print as a synonym for =, for the benefit of LaserPrep. + + Implements non-zero PaintType for the show operators (but not for + charpath) for Type 1 fonts. + + Adds the ISOLatin1Encoding encoding vector. + + Renames currentcolor and setcolor as currentgscolor and setgscolor, to + avoid conflict with the Level 2 PostScript names. Removes colorhsb, + colorrgb, hsbcolor, and rgbcolor. + + Library + ------- + + Fixes bugs: + - In a couple of places, a 0 was being passed as a pointer + argument without casting, which confused the Microsoft C compiler. + - Image devices were not recognized properly in debugging + configurations. + - Inverted-color monochrome image devices were not recognized + properly. + - Images that exactly fill the drawing area rendered very slowly, + because they erroneously used the general clipping algorithm. + - Images that are 1-for-1 with the device were incorrectly scaled + by a factor of 8 in X. + - Rounding artifacts sometimes caused characters to be unevenly + offset vertically by 1 pixel. + - Type 1 fonts that used the Flex feature resulted in garbled + images. + - The show operator routines would incorrectly fill or stroke a + path that existed at the time the show was started. + - setscreen truncated the cell size instead of rounding, which + could produce off-by-1 anomalies. + - stroke would sometimes produce garbage (or nothing at all) for + very narrow lines. + - path filling would only color the pixels whose centers fell + inside the path: the Adobe specification requires coloring a pixel if any + part of it falls inside the path. + + Changes the Epson printer driver so that it drives the printer directly + rather than writing to a file. + + Changes pathbbox so that if the path is empty but there is a current + point, it returns a null rectangle at the current point. + + Changes gs_image_init to take an additional parameter (after bps) giving + the number of samples per pixel (1, 3, or 4), and an indication of whether + the samples for each pixel are together or separated (-3 or -4). + + Renames the gs_image_data and gs_imagemask_data procedures as gs_image and + gs_imagemask, and removes the old versions of the latter. + + Adds gs_colorimage. + + Replaces Snoopy's color dithering algorithm with one contributed by Paul + Haeberli. + + Changes gs_setgray, gs_[set]hsbcolor, and gs_[set]rgbcolor so that they + coerce arguments outside the range [0..1] back into the range, instead of + signalling an error. + + Makes a number of minor changes required to pacify the Microsoft C + compiler. + + Changes gs_arcto so that if the last argument is a null pointer, the + tangent points are not returned. + + Removes gs_type1addpath, which is not useful. (Clients must call + gs_type1_init and gs_type1_interpret directly.) + + Implements the 'seac' opcode for Type 1 fonts, allowing fonts with accented + characters to display properly. + + Implements the undocumented 'testadd' opcode for Type 1 fonts, which is + used by some Adobe fonts. + + Renames gs_currentcolor and gs_setcolor as gs_currentgscolor and + gs_setgscolor. Removes gs_colorhsb, gs_colorrgb, gs_hsbcolor, and + gs_rgbcolor. + + Version 2.0 (9/12/90) + =========== + + The main purpose of this release is to add fonts, support for multiple + devices, and imaging into memory. It also fixes a number of miscellaneous + bugs. (Unfortunately, accurate records of the bugs fixed are not + available.) The changes were so extensive that we chose to increment the + major version number. + + Miscellaneous + ------------- + + Doesn't attempt to open the .MAP file on Unix systems. + + Adds mention of statusd.ps to interp.doc. + + Notes that Turbo C 2.0, not 1.5, is required for building the MS-DOS + version. + + Adds a DEVICES= line to the makefile, and allows multiple devices. + + Documents, in interp.doc, the X Windows resources that Ghostscript + recognizes. + + Adds three PostScript masters to the fileset: chess.ps (+ cheq.ps), + golfer.ps, and escher.ps. + + Drivers + ------- + + Changes the names of all the device drivers. See gdevs.mak for the + updated list. + + Adds a (working) driver for SunView. + + Adds drivers for the Sony NeWS frame buffer, and the Sony Microsystems + NWP533 printers. These drivers were contributed by users, so we aren't + prepared to answer questions about them. + + Adds a driver for the Borland Graphics Interface (BGI) for MS-DOS systems. + Note that to use this driver with a non-EGA/VGA display, you need a .BGI + file appropriate for your hardware. (The Ghostscript executable includes + the EGA/VGA driver.) + + Adds a driver for Epson printers. The driver has only been tested on an + LX-800, and on an H-P DeskJet in FX-80 emulation mode, but may work on + other models. The driver could be adapted to work on Unix systems, but as + distributed, it only works on MS-DOS systems. + + Adds a driver for the Hewlett-Packard DeskJet printer. The driver could + be adapted to work on Unix systems, but as distributed, it only works on + MS-DOS systems. + + The X Windows driver no longer waits for the user to type a character + before bringing up the initial display. + + Adds information to drivers.doc describing how to change the definition of + the device structure and procedure table. + + Extends the tile_rectangle and tile_trapezoid driver procedures to + interpret color0 = color1 = gx_no_color_index as meaning that the tile is + actually colored, not a mask. + + Build procedures + ---------------- + + Changes the tar file so it puts everything in a directory called gs. + + Removes the -ansi switch for gcc (this was causing problems with + on some systems). + + Changes LDPLAT to the string -X, which is appropriate for most Unix + systems (but not for SunOS 4.n). + + Adds EXTRALIBS to the makefile, for specifying additional libraries to be + linked in. + + Adds a 'clean' target for 'make', to get rid of all temporary files, the + binaries, and the executable. + + Changes names of system-specific files from gp-xxx.c to gp_xxx.c. + + Adds support for VMS (gp_vms.c and ghost.dcl). + + Creates a new file gdevs.mak, and reorganizes the other makefiles, so that + the choice of which device driver(s) to include is isolated in a single + line in the platform-specific makefile. + + Changes the standard MS-DOS makefile so it builds for 8088/86 (not 80386), + with neither -DNOPRIVATE nor -DDEBUG. + + Changes the name of the MS-DOS makefile from dos-ega.mak to msdos.mak, and + the Unix makefiles from ux-[g]cc-x.mak to unix-[g]cc.mak. + + Updates drivers.doc to describe how to add new drivers in gdevs.mak. + + Removes gdevs.ps: the drivers are now responsible for specifying the size + of the imaging region. + + Interpreter + ----------- + + Adds a makefile macro GS_LIB_DEFAULT and an environment variable GS_LIB to + define a search path for the library (initialization and font) files, and + implements the -I switch for the same purpose (replacing -sLIB=, which was + never actually implemented). See interp.doc for details. + + No longer clears the operand stack between interactive inputs. No longer + prints the contents of the operand stack after every input in debug mode. + + Doesn't "eat" the character that the user types to proceed after a + showpage, unless it's an isolated . + + Changes the prompt so that it says + GS> + if the operand stack is empty, or + GS + if there are n > 0 elements on the operand stack. + + Adds -w and -h switches to the command line, equivalent to -dWIDTH= and + -dHEIGHT= except that they require numeric arguments. + + Adds -q (quiet startup) switch to the command line, which suppresses some + initial messages and also has an effect equivalent to -dQUIET. + + Fixes bugs: + - = and == caused an error on some kinds of objects if the object + didn't have read access. + - cvs didn't print operator names. + - The definition of dynamic_begin in iscan.c caused the DEC VMS C + compiler to produce incorrect code. + - mul didn't return a correct (real) result when multiplying a + very large integer by an integer that wasn't very large. + - eq and ne didn't work on files, fonts, save objects, and some + operators. + - The scanner would sometimes blow up on floating point numbers + beginning with a '.'. + - flushfile didn't pop its argument from the stack. + - put and putinterval would store into a packed array. + - a few operators didn't check properly for stack underflow. + - cvrs produced wrong output for radix values greater than 10. + - The scanner would convert upper-case letters in alternate-radix + numbers wrong on Unix systems. + - String comparisons other than equality often produced the wrong + result if the strings were of different lengths. + - An ifelse as the last thing inside a forall would confuse the + execution stack. + - There were some omitted casts and 'private' declarations that + made the GNU compiler unhappy. + - There was a memory leak in the image[mask] operators that caused + 516 bytes to be permanently lost each time one of them was used. + - Quoted strings of length greater than 50 and less than 100 would + get mangled when being read in. + - The scanner didn't consume the whitespace character following a + token, so programs that read data out of the program file could get + confused. + - Under rare circumstances, an object of size between 249 and 255 + bytes could get allocated on top of another object. + + Allows bind to bind packed arrays, even though they aren't normally + writable. + + Changes the length operator to allow a name as the argument. (The + PostScript manual doesn't allow this, but implementations apparently do.) + + Changes the setcachedevice operator to allow the bounding box to be + specified as a 4-element array instead of 4 scalars. (The PostScript + manual doesn't allow this, but implementations apparently do.) + + Removes a line from ghost.ps that accidentally disabled the font cache. + + Implements memory devices (makeimagedevice, copyscanlines, and makedevice + for image devices). makeimagedevice is implemented only for 1, 8, 24, and + 32 bits per pixel. + + Changes the deviceparams operator so it pushes a mark on the stack below + the parameters. This is to allow for devices that have more than the + standard set of parameters. + + Replaces defaultdevicename with two new operators, getdevice and + devicename. + + Adds a flushpage operator that flushes any outstanding buffered output to + the screen. This is not the same as copypage: on printers, copypage + actually prints a page, whereas flushpage may do nothing; on displays, + flushpage and copypage may both flush output to a server. + + Adds an unread operator for pushing back a character into a file. + + Adds a description of proposed grayimage and colorimage operators to + ghost.doc, even though they aren't implemented yet. + + Changes the name of the currentfileposition operator to fileposition. + + Removes the framedevice operator, since the new device operators supersede + it. + + Adds a writeppmfile operator, for writing the contents of a memory device + to a ppm file. + + Makes Ghostscript work even when the >> operator doesn't sign-extend + negative numbers. (This has not been tested.) + + Adds the Symbol encoding to ghost.ps. + + Adds two new file-related operators, filename and findlibfile. See + ghost.doc and interp.doc for details. + + Adds type1encrypt and type1decrypt operators for manipulating Adobe Type 1 + encoded fonts. + + Changes the imagecharpath and addcharpath operators to type1imagepath and + type1addpath. These operators now work with the Adobe Type 1 font + encoding. + + Adds the type1decryptfile operator for reading Adobe Type 1 encrypted + fonts. + + Library + ------- + + Fixes bugs: + - curveto and lineto didn't check for the current point being + defined. + - stringwidth would fail if there was no current point. + - There were omitted casts that made the GNU compiler unhappy. + - Line caps and joins didn't always work. + - Dashed lines didn't work at all. + - If you read out the current matrix while inside a BuildChar + procedure, the result was garbage. + - image[mask] would crash if you gave it a single string with more + than 64K-1 pixels (MS-DOS only). + - Filling with a gray pattern sometimes wrote into pixels beyond + the right edge of the region (MS-DOS only). + - The font cache would mistake fonts for each other if both fonts + had a default (unsupplied) "unique ID". + - When a character was entered into the font cache for the first + time, sometimes it would display as garbage and/or displaced vertically + from its proper position. + + Implements gs_makeimagedevice, gs_copyscanlines, gs_getdevice, + gs_devicename, gs_flushpage, gs_writeppmfile, gs_type1encrypt, + gs_type1decrypt, gs_type1imagepath, and gs_type1addpath procedures + corresponding to the new operators in the interpreter (see preceding + section). + + Changes [gs_]setdevice so that it does an erasepage when it first opens + the device. + + Changes definition of gx_device structure as follows. NOTE: THIS AFFECTS + ALL DRIVERS. + + - Removes bits_from_MSB (which wasn't actually used, in any case). + Ghostscript now assumes officially, as it always did in + practice, that device bitmaps are stored MSB first, i.e., X=0 + corresponds to the 0x80 bit in the first byte. + + - Removes the initial_matrix member, which wasn't actually being + set up. + + - Adds a new member 'name', a string giving the device name. + + - Adds new members 'x_pixels_per_inch' and 'y_pixels_per_inch'. + These are only used by the default initial_matrix procedure + (see below). + + - Adds a new procedure 'output_page'. The default implementation + (gx_default_output_page) just calls the sync_output procedure. + + - Adds a new procedure 'get_initial_matrix'. The default + procedure uses the width, height, and x/y_pixels_per_inch + members to compute the matrix, assuming that X values run from + right to left, and Y values run from top to bottom. + + Changes the names of the allocation procedure types gs_proc_alloc and + gs_proc_free to proc_alloc_t and proc_free_t, and moves them from gs.h to + std.h. + + Makes Ghostscript work even when the >> operator doesn't sign-extend + negative numbers. (This has not been tested.) + + Version 1.3 (6/20/89) + =========== + + This release should have had a lot more things in it, but time pressure + and the already long delay in getting it out made it necessary to push it + out the door in an incomplete state (e.g., no testing on X systems + whatsoever). + + Interpreter + ----------- + + Makes -d and -D equivalent on the command line. Adds a new switch -s / -S + that defines a name as a string rather than a token. + + Arranges things so that if -sLIB=_a_prefix_ is defined on the command + line, (filename) run will look for _a_prefix_filename before giving up if + filename isn't the name of an accessible file. + + Changes showpage from an operator to a procedure. The definition of + showpage in ghost.ps does a copypage, beeps the console, waits for the + user to type a character (normally a , since line buffering is + always enabled), and then does an erasepage and an initgraphics. + + Adds a new initialization file, gdevs.ps, containing device-dependent + parameters. The default window size for X Windows is properly set to 612 + x 792, i.e., 8.5" x 11". + + Adds a new optional initialization file, statusd.ps, that provides dummy + definitions for the names found in statusdict on LaserWriters. + + Adds a new operator, getenv, to get information from the shell + environment. + + Adds a new predefined operator, defaultdevicename, that returns either (X) + or (EGA) according to how the interpreter was built. + + Adds a new type, devicetype, and new operators deviceparams, getscanlines, + makedevice, makeimagedevice, and setdevice. Changes currentdevice to + return a device object rather than a set of parameters. + + Makes the scanner recognize reals with 'e' exponent notation, and handle + reals with more than 9 digits. + + Fixes a bug that made names starting with digits read incorrectly. + + Fixes a bug in the exp operator that made it not pop its first argument + from the stack. + + Fixes a bug in the rand operator that made it return negative values about + half the time. + + Fixes a bug in equality comparison (eq, ne, and several other operators) + that made unequal operator objects occasionally appear to be equal on DOS + systems. + + Fixes a bug in the bind operator that made it not work on packed arrays. + + Changes the internal representation of dictionaries so they can be + expanded or contracted dynamically. Adds a new operator, setmaxlength, to + change the allocated size of a dictionary. + + Changes sstorei.h so that non-DOS compilers don't encounter the #pragma + directive used by Turbo C. + + Restores the display mode (on MS-DOS systems) when exiting. + + Fonts + ----- + + Makes undefined characters in the standard font display as tilde rather + than blank (or causing an error). Unmapped character codes (those mapped + to .notdef in the encoding) still display as nothing, per the PostScript + manual. + + Library + ------- + + Adds a new header file, gxbitmap.h, with some new documentation describing + the internal storage format for bitmaps. + + Makes numerous internal changes in the character / font cache, affecting + many of the routines in gxcache.c. + + Fixes a bug in gz_draw_line / gz_fill_trapezoid that made nearly + horizontal lines display wrong. + + Fixes a bug in gs_scale that made scaling not work if the coordinate + system was rotated or skewed. + + Extends the font cache so it will handle characters rotated by multiples + of 90 degrees. + + Changes the second argument of gx_path_bbox and gx_path_is_rectangle to be + a gs_fixed_rect * rather than a fixed [4]. + + Changes gs_matrix_rotate so it handles multiples of 90 degrees as a + special case. + + Changes the definition of the gx_device structure to accommodate the new + device operators, and adds corresponding library calls. + + Changes the type for a device color index from int to gx_color_index + (equivalent to unsigned long). ***NOTE***: this affects existing clients + and drivers in a non-trivial way on MS-DOS systems. + + Changes gs_malloc and gs_free to take a client name string as an argument. + + Usage procedures + ---------------- + + Changes the compilation rules for Unix systems to not use the -o and -c + compiler flags together, to be compatible with more versions of cc. + + Changes the gcc makefile to use $(GCC) rather than gcc as the compiler + name. + + Moves the -1 flag for the MS-DOS compiler from the cc*.bat files to the + makefile. + + Changes CCDEBUG to CCFLAGS, and adds ASMFLAGS, in DOS makefile. + + Adds -DFOR80386 and /DFOR80386 to enable use of 80386 instructions in + assembly code on DOS systems. + + Merges the DEBUG and gs_DEBUG switches. There is now only a single DEBUG + switch that affects both the interpreter and the library. + + Adds a new compilation switch, -DNOPRIVATE, that makes private (static) + variables and procedures public for debugging and profiling (only needed + on DOS systems). + + Adds the DOS executable (gs.exe and gs.map) to the distribution fileset. + + Adds new platform-specific code files, gp-*.c, for a few things like + reading the clock. + + Adds a new documentation file, drivers.doc, that describes the interface + between Ghostscript and device drivers. + + Version 1.2 (2/22/89) + =========== + + Interpreter + ----------- + + Adds the new facilities in version 25 of PostScript: //name for immediate + lookup, packed arrays (setpacking, currentpacking, packedarray operators), + and new font cache parameters (setcacheparams, currentcacheparams + operators). + + Adds new operators (setfileposition, currentfileposition) for random + access to files. + + Extends readhexstring to take either a string or a file, just like token. + + Fixes a bug that caused the 'for' operator (and a couple of others) to + randomly smash memory locations on PC platforms. + + Library + ------- + + Renames the init_device driver procedure as open_device, and adds a + corresponding close_device. + + Adds new procedures to read and set the cache limit values (implementing + the currentcacheparams and setcacheparams operators). + + Usage procedures + ---------------- + + Changes the name of the Unix makefile to ux-cc-x.mak, and adds a new Unix + makefile, ux-gcc-x.mak, for using gcc instead of cc. (The latter doesn't + actually work yet.) + + Changes the name of the single built-in font from uglyfont.cp to + ugly10.cp. + + Version 1.1 (2/12/89) + =========== + + Interpreter + ----------- + + Makes the scanner treat ^Z (ASCII code 26) as whitespace: it erroneously + treated ^R (ASCII code 22, or octal 26) as whitespace. + + Makes the token and readline operators, and the syntax for comments, + recognize \r (code 13), \n (code 10), and \r\n as equivalent end-of-line + indicators. The token and readline operators will skip over any of these + sequences at the end of a token or line respectively, and a comment will + read through any of these sequences. The other file operators (read, + write, readstring, writestring) do nothing special with these characters. + + Changes the debug switch name from -D to -Z. Adds a -D switch for + defining names in systemdict from the command line. Defines -DDEBUG for + printing out debugging information during initialization, and -DNODISPLAY + for suppressing display output. + + Corrects a bug that prevented the error machinery from working -- in + version 1.0, errors always dumped the stacks and aborted interpretation. + + Corrects a bug that made eq and ne not work for strings. + + Makes the atan (arctangent) operator normalize its results according to + the PostScript convention. + + Makes the div operator check for zero divisor. + + Makes unimplemented operators (resetfile, echo, save, restore, strokepath, + reversepath) truly undefined. + + Makes the interactive loop exit gracefully on end-of-file: in version 1.0 + this caused an infinite loop. + + Implements the status operator. + + Corrects a bug that made the 'for' operator deliver garbage values if one + or more of the operands (start, increment, end) was a real. + + Corrects a bug that made the arc and arcn operators not pop their operands + from the stack. + + Corrects a bug that made the kshow operator crash the interpreter. + + Corrects a bug that made the print operator fail on machines that don't + pass structure arguments by simply pushing the contents of the structure. + + Adds a new operator, imagecharpath, to convert images to + addcharpath-compatible outlines. + + Changes alloc and alloc_free to use char * rather than byte *, and + alloc_free to return void rather than int, making them compatible with the + library's expectations and with malloc/free. + + Explicitly casts all expressions of the form (ptr1 - ptr2) used as + procedure arguments to unsigned, to handle an incompatibility between + Turbo C versions 1.5 and 2.0. + + Changes some of the internal conventions for operators: operators that + push on the operand stack must check for overflow explicitly, and + operators that modify the execution stack must return a special code. + (See oper.h for details.) + + Initialization (ghost.ps, gfonts.ps) + -------------- + + Modifies ghost.ps and gfonts.ps so they print debugging information only + if the name DEBUG is defined. (Presumably the user will set this from the + command line with -DDEBUG.) + + Changes ghost.ps so it initializes the nominal screen size to 640 x 350 on + MS-DOS systems as before, but to 612 x 792 on Unix systems, which is an + 8.5" x 11" page at 72 pixels per inch. + + Library + ------- + + Corrects a bug that made the fill and eofill operators (gs_fill and + gs_eofill) not perform a newpath afterward. + + Corrects the bug that made thin, nearly horizontal lines display wrong (as + a series of disconnected dots) in the MS-DOS implementation. + + Fixes a bug in the EGA driver that often made it fill rectangular regions + with black around information being displayed in white. + + Completely changes the internal representation of outline fonts, and + changes btoi.ps (a Ghostscript language program for converting bitmaps to + outlines) to use a new library call, gs_imagecharpath. + + Changes the extension for outline font files from .gf to .cp. + + Adds a new debugging switch, q, that traces all rectangle fill operations. + + Adds a new debugging switch, v, that traces all device-level output calls. + + Explicitly casts pointer differences passed as procedure arguments, as in + the interpreter. + + Makes stringwidth work if there is no current point. In version 1.0, this + gave a nocurrentpoint error. + + Usage procedures + ---------------- + + Changes the name of the 'read me' file from READ.ME to README. + + Removes a bogus line (invoking the 'mcopy' utility) from the makefile. + + Splits up the makefile into a generic part (ghost.mak) and + platform-specific parts (dos-ega.mak, unix-x11.mak). The latter are what + is actually executed. + + Puts the definitions of the DEBUG and gs_DEBUG compilation flags into the + makefile instead of in ghost.h and gx.h respectively. + + Changes the names of the documentation files to be a little less cryptic. + Changes all the file names to lower-case in the documentation. Adds + installation information to make.doc. + + Changes all function definitions (but not prototype declarations) to ANSI + syntax, and adds a preprocessing step (ansi2knr) to convert them to K&R + syntax on Unix systems. + + Changes the normal MS-DOS link configuration to not assume the presence of + an 80x87 coprocessor, and describes how to increase performance if a + coprocessor is present. + + Changes the names of all the interpreter .c files, except stream.c, to + begin with 'i'. + + Version 1.0 (8/11/88) + =========== + + First version released to the public. diff -rc2N gs241/README gs25/README *** gs241/README Mon Apr 20 03:41:04 1992 --- gs25/README Wed Aug 19 00:55:27 1992 *************** *** 20,26 **** - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! ***************************************************** ! * This file describes version 2.4.1 of Ghostscript. * ! ***************************************************** ******** --- 20,26 ---- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! *************************************************** ! * This file describes version 2.5 of Ghostscript. * ! *************************************************** ******** *************** *** 30,39 **** Ghostscript is the name of a set of software that provides: ! - An interpreter for the Ghostscript language, which very ! closely resembles the PostScript (TM) language; and - A set of C procedures (the Ghostscript library) that implement the graphics capabilities that appear as primitive ! operations in the Ghostscript language. The Ghostscript language interpreter and library are written entirely --- 30,38 ---- Ghostscript is the name of a set of software that provides: ! - An interpreter for the PostScript (TM) language, and - A set of C procedures (the Ghostscript library) that implement the graphics capabilities that appear as primitive ! operations in the PostScript language. The Ghostscript language interpreter and library are written entirely *************** *** 43,54 **** - IBM PC and compatibles with EGA, VGA, SuperVGA, or compatible ! graphics under MS-DOS 3.1, 3.3, or 5.0; - A wide variety of Unix systems using X Windows version 11, release 3, 4, and 5, including Sun-3, Sun-4, Sun-386i, ! Sun SPARCStation 1; generic 80386 machines running 386/ix; ! H-P 9000/300 and 9000/800; DECStation 2100 and 3100; VAX ! running Ultrix; Sequent Symmetry; Convex C1 and C2; ! Tektronix 4300; SGI Iris Indigo; - Sun workstations (Sun-3, SPARC, Sun-386i) running SunView; --- 42,54 ---- - IBM PC and compatibles with EGA, VGA, SuperVGA, or compatible ! graphics under MS-DOS 3.1, 3.3, or 5.0, with or without ! Microsoft Windows 3.0 or 3.1; - A wide variety of Unix systems using X Windows version 11, release 3, 4, and 5, including Sun-3, Sun-4, Sun-386i, ! Sun SPARCStation 1 and 2; generic 80386 machines running 386/ix, ! ISC Unix, and SCO Unix; H-P 9000/300 and 9000/800; ! DECStation 2100 and 3100; VAX running Ultrix; Sequent Symmetry; ! Convex C1 and C2; Tektronix 4300; SGI Iris Indigo; - Sun workstations (Sun-3, SPARC, Sun-386i) running SunView; *************** *** 69,72 **** --- 69,86 ---- ******** + ******** Related programs + ******** + + There are two freely available screen previewers based on + Ghostscript: Ghostview and GSPreview. For information on Ghostview, + contact Tim Theisen (ghostview@cs.wisc.edu). For information on + GSPreview, contact Richard Hesketh (rlh2@ukc.ac.uk). + + A set of patches and additions for Kanji capability for Ghostscript + version 2.4.1 is available for anonymous FTP from + ftp.cs.titech.ac.jp:GNU/gs241j11.tar.Z. For more information, contact + Mr. Norio Katayama (katayama@nacsis.ac.jp). + + ******** ******** Documentation overview ******** ******** *************** *** 76,114 **** On MS-DOS systems, all file names are actually upper-case. ! Files of interest to most users (both previous and new) ! ------------------------------------------------------- > README - this file. ! > readme.doc - information about problems and new features in the ! current release. ! If you have used a previous release of Ghostscript, you should also ! read any more recent sections of history.doc. ! Files of particular interest to new users ! ----------------------------------------- ! > fonts.doc - information about the fonts distributed with Ghostscript. ! > language.doc - A description of the Ghostscript language. > make.doc - how to install, compile and link Ghostscript. > psfiles.doc - information about the .ps files distributed with Ghostscript (other than fonts). ! > use.doc - information about to use Ghostscript. ! Files of interest to fewer users ! -------------------------------- > drivers.doc - the interface between Ghostscript and device drivers. > hershey.doc - information about the Hershey fonts, which are the basis of some of the Ghostscript fonts. - > history.doc - history of changes in Ghostscript releases. - > humor.doc - a humorous comment on Ghostscript contributed by a net.person. --- 90,145 ---- On MS-DOS systems, all file names are actually upper-case. ! When you receive Ghostscript, you should start by reading: > README - this file. ! > readme.doc - information about problems and major changes new ! features in the current release. ! ! If you have used a previous release of Ghostscript, you probably ! should also read any more recent sections of: ! ! > NEWS - a complete, detailed history of changes in Ghostscript ! releases. ! Especially for new users ! ------------------------ ! If you are a new user of Ghostscript, you should read: ! > use.doc - information about to use Ghostscript. ! If you are going to compile Ghostscript, rather than just use an ! executable you got from somewhere, you should read: > make.doc - how to install, compile and link Ghostscript. + If you run into any questions, or if you are going to be using + Ghostscript extensively, you should at least skim, and probably + eventually read: + + > fonts.doc - information about the fonts distributed with + Ghostscript, including how to add or replace fonts. + + > language.doc - A description of the Ghostscript language, and its + differences from the documented PostScript language. + > psfiles.doc - information about the .ps files distributed with Ghostscript (other than fonts). ! Especially for developers ! ------------------------- ! If you are going to be writing a new driver for Ghostscript, you ! should read: > drivers.doc - the interface between Ghostscript and device drivers. + Odds and ends + ------------- + > hershey.doc - information about the Hershey fonts, which are the basis of some of the Ghostscript fonts. > humor.doc - a humorous comment on Ghostscript contributed by a net.person. *************** *** 121,146 **** ******** ! If you have problems with Ghostscript, and you have access to Usenet ! news, we suggest you post your question to gnu.ghostscript.bug. ! There are hundreds of Ghostscript user sites all over the world, and ! often another user will be able to help you. ! ! If you wish to contact Aladdin Enterprises directly, you may reach us ! at: ! Aladdin Enterprises ! P.O. box 60264 ! Palo Alto, CA 94306 ! (415)322-0103 ! ...{uunet,decwrl}!aladdin!ghost ! ghost@aladdin.com ! If you call on the phone, you will usually be talking to an answering ! machine. In this case, please leave a message with your name and ! phone number and the best time for us to return the call. ! Because Ghostscript is distributed so widely, Aladdin Enterprises ! doesn't have the resources to respond to everyone by e-mail. We only ! promise to respond to e-mail from the following classes of users: - Beta testers who have actually given us at least one report on --- 152,188 ---- ******** ! Aladdin Enterprises doesn't have the resources to respond to questions ! from general users of Ghostscript. If you have problems with ! Ghostscript, and you have access to Usenet news, we suggest you post ! your question to gnu.ghostscript.bug. There are hundreds of ! Ghostscript user sites all over the world, and often another user will ! be able to help you. If you are having trouble with a specific device ! driver, look in the file devs.mak and see if it is a user-maintained ! driver. If so, you may contact the person listed there directly; ! please do not contact Aladdin Enterprises regarding user-maintained ! drivers. ! ! Aladdin Enterprises does want Ghostscript to be of high quality, so if ! you have been running Ghostscript and encounter a problem, we will be ! glad to investigate it if you meet all the following criteria: ! ! - You are using the most recent version of Ghostscript. ! ! - You obtained Ghostscript directly from Aladdin Enterprises, ! or from a GNU distribution site on the Internet. ! ! - You have installed Ghostscript successfully, and used it ! successfully on other input data. ! ! - Your problem is reproducible, and you can send us the input ! data that evokes it (by e-mail, anonymous FTP, or PC diskette). ! - Your bug report tells us what hardware, operating system, ! window system, and C compiler you are using. ! Bug reports that include suggested fixes are especially welcome. ! As time permits, Aladdin Enterprises will also respond to e-mail from ! the following classes of users: - Beta testers who have actually given us at least one report on *************** *** 155,171 **** - Commercial licensees. - We also appreciate and welcome detailed, well-documented bug reports - from anyone, especially if they include a fix. - - We do read gnu.ghostscript.bug and respond to significant problems - reported there, as time permits. - - If you report a problem by e-mail, please specify which version of - Ghostscript you are running, and the hardware, operating system, - window system, and C compiler you are using, and be as specific as - you can about the problem -- this will help us a lot in tracking it - down. We want Ghostscript to be a high-quality product, and will do - our best to fix any reported problem. - Given the choice between the Internet and the UUCP address, remember that the Internet is not to be used for general commercial traffic: --- 197,200 ---- *************** *** 176,180 **** software: ! 80486 PC, MS-DOS 5.0, Borland C++ 3.0 (and several older versions); color SuperVGA display; Epson-compatible printer (the printer also is compatible with the IBM Proprinter); --- 205,210 ---- software: ! 80486 PC, MS-DOS 5.0, Microsoft Windows 3.0; ! Borland C++ 3.1 (and several older versions); color SuperVGA display; Epson-compatible printer (the printer also is compatible with the IBM Proprinter); *************** *** 181,185 **** various H-P printers; Canon BubbleJet. ! SPARCstation, SunOS 4.0, cc and gcc, X11R5 and SunView; both monochrome and color displays. --- 211,215 ---- various H-P printers; Canon BubbleJet. ! SPARCstation, SunOS 4.1, cc and gcc, X11R5 and SunView; both monochrome and color displays. *************** *** 190,193 **** --- 220,238 ---- will have to rely on other users to help. + If you wish to contact Aladdin Enterprises directly, you may reach us + at: + + Aladdin Enterprises + P.O. box 60264 + Palo Alto, CA 94306 + voice (415)322-0103 + (no fax yet, but soon) + ...{uunet,decwrl}!aladdin!ghost + ghost@aladdin.com + + If you call on the phone, you will usually be talking to an answering + machine. In this case, please leave a message with your name and + phone number and the best time for us to return the call. + ******** ******** Things you can do to help ******** *************** *** 227,236 **** this is of interest to you. - Another thing we need a volunteer to help with is maintaining the - SunView driver. Since nearly all SunView sites have switched to - OpenWindows or plain X Windows, we (Aladdin Enterprises) plan to stop - updating it sometime fairly soon. Please contact ghost@aladdin.com - if you are willing to help with this. - ******** ******** Authors ******** --- 272,275 ---- *************** *** 248,251 **** --- 287,291 ---- Karl Berry and Kathy Hargreaves (for helping create the fonts distributed with Ghostscript), + George Cameron (for a DeskJet 500C driver), Phil Conrad (for originating the PPM utilities and the PCX and GIF drivers, and lots of bug reports), *************** *** 256,268 **** Paul Haeberli (for the ideas behind better color selection and trapezoid fill algorithms), ! Alfred Kayser (for the DeskJet 500C driver and beta testing), Richard Keeney (for help with the SunView driver), Eleftherios Koutsofios (for help with the SunView driver), Markku Koppinen (for a better circle-to-curve algorithm), Jim Mayer (for improving the DeskJet driver), ! Richard Mlynarik (for many improvements and suggestions), Ulrich Mueller (for the LN03 driver), ! Daniel Newman (for major help with VMS), ! Roque Donizete de Oliveira (for testing and debugging), Marc Paquette (for the original PaintJet driver), Hal Peterson (for major help with BDF fonts), --- 296,316 ---- Paul Haeberli (for the ideas behind better color selection and trapezoid fill algorithms), ! Richard Hesketh (for GSPreview), ! Thomas Hiller (for the Trident TVGA driver), ! Frans van Hoesel (for improvements to the DeskJet driver), ! Alfred Kayser (for a DeskJet 500C driver and beta testing), Richard Keeney (for help with the SunView driver), Eleftherios Koutsofios (for help with the SunView driver), Markku Koppinen (for a better circle-to-curve algorithm), + Russell Lang and Maurice Castro (for the first working Microsoft + Windows driver), + Ian MacPhedran (for a sixel driver), Jim Mayer (for improving the DeskJet driver), ! Richard Mlynarik (for a nearly overwhelming volume of ! improvements and suggestions), Ulrich Mueller (for the LN03 driver), ! Daniel Newman (for major help with VMS and the CCITT Fax filters), ! Roque Donizete de Oliveira (for testing and debugging, ! and a 'man' page), Marc Paquette (for the original PaintJet driver), Hal Peterson (for major help with BDF fonts), *************** *** 273,276 **** --- 321,325 ---- Clemens Schrimpe (for help with accented characters), Mike Smolenski (for the Sony drivers), + Karsten Spang (for the Tektronix ink-jet driver), Andreas Stolcke (for help with the SunView driver), Snoopy (for major help with Hershey fonts, and many other *************** *** 277,280 **** --- 326,331 ---- contributions), Michael Sweet (for help with the high-density Epson driver), + Tim Theisen (for help with the X Windows driver, and for the + Ghostview previewer that is built on Ghostscript), Gregg Townsend (for the low-resolution dithering algorithm), Christian Tschudin (for fixes to the virtual memory package, *************** *** 282,285 **** --- 333,337 ---- Jos Vos (for the original PBM/PGM/PPM driver), Allan Wax (for the AT&T 6300 modification to the BGI driver), + David Wexelblat (for the high-resolution 9-pin Epson driver), Elizabeth Zwicky (for some very challenging examples). *************** *** 294,302 **** Mark Friedman, Richard Foulk, Glenn Geers, Dave Goldblatt, Dirk Grunwald, ! Lars Haakedal, Adam Hammer, George Hartzell, Thomas Hiller, ! Mike Hoffmann, Brad Jones, Terry Jones, David Keppel, ! Russell Lang, Anthony Lee, John Lundin Jr., Lee McLoughlin, Stergios Marinopoulos, Herb Martin, David Maynard, Doug McDonald, Rich Murphey, --- 346,353 ---- Mark Friedman, Richard Foulk, Glenn Geers, Dave Goldblatt, Dirk Grunwald, ! Lars Haakedal, Adam Hammer, George Hartzell, Mike Hoffmann, Brad Jones, Terry Jones, David Keppel, ! Anthony Lee, John Lundin Jr., Lee McLoughlin, Stergios Marinopoulos, Herb Martin, David Maynard, Doug McDonald, Rich Murphey, *************** *** 305,309 **** Mark Rawling, Philippe Robert, Tomas Rokicki, Wolfgang Rupprecht, Bill Schelter, Bakul Shah, ! Erik Talvola, Tim Theisen, Amanda Walker, Peter Wan, Carsten Wiethoff, Carl Witty, Frank Yellin, --- 356,360 ---- Mark Rawling, Philippe Robert, Tomas Rokicki, Wolfgang Rupprecht, Bill Schelter, Bakul Shah, ! Erik Talvola, Amanda Walker, Peter Wan, Carsten Wiethoff, Carl Witty, Frank Yellin, diff -rc2N gs241/alphabet.ps gs25/alphabet.ps *** gs241/alphabet.ps Sat Apr 18 15:43:22 1992 --- gs25/alphabet.ps Tue Jun 23 05:56:34 1992 *************** *** 1,15 **** ! (Courier) findfont 10 scalefont setfont ! currentfont 1.5 scalefont setfont ! /sp ( !"#$%&'\(\)*+,-./ [[\\\\]]^^__ `{|}~) def ! /sd (001122334456789<=>:;?@) def ! /smaj (ABCDEFGHIJKLMNOPQRSTUVWXYZ) def ! /smin (abcdefghijklmnopqrstuvwxyz) def ! 20 0 moveto ! 4 { ! [ sp sd smaj smin ] ! { 0 15 rmoveto gsave show grestore ! } forall ! 1.6 1.6 scale ! } repeat showpage --- 1,50 ---- ! % Check for command line parameters: ! % Name, FirstSize, Ratio, NumSizes, UseOutline. ! /Name where { pop } { /Name (Courier) def } ifelse ! /FirstSize where { pop } { /FirstSize 15 def } ifelse ! /Ratio where { pop } { /Ratio 1.6 def } ifelse ! /NumSizes where { pop } { /NumSizes 3 def } ifelse ! /UseOutline where { pop } { /UseOutline false def } ifelse ! ! /Strings FirstSize 20 gt ! { [ ! (ABCDEFGHIJ) (KLMNOPQR) (STUVWXYZ) ! (abcdefghijklm) (nopqrstuvwxyz) ! (0123456789<=>) (:;?@ !"#$%&') ! (\(\)*+,-./[\\]^_) (`{|}~) ! ] } ! { [ ! (ABCDEFGHIJKLMNOPQRSTUVWXYZ) ! (abcdefghijklmnopqrstuvwxyz) ! (0123456789<=>:;?@ !"#$%&') ! (\(\)*+,-./ [\\]^_ `{|}~) ! ] } ! ifelse def ! ! /sshow ! { gsave UseOutline ! { { gsave ( ) dup 0 4 -1 roll put ! false charpath pathbbox 0 setlinewidth stroke grestore ! pop 8 add currentpoint exch pop moveto pop ! } forall ! } ! { 2 0 3 -1 roll ashow } ! ifelse grestore ! } def ! ! Name findfont FirstSize scalefont setfont ! ! 10 -10 moveto ! NumSizes ! { gsave nulldevice (Q) false charpath pathbbox grestore ! exch pop exch sub exch pop 1.25 mul /height exch def ! Strings ! { dup 0 height rmoveto sshow ! UseOutline not ! { 0 height rmoveto gsave 0.01 rotate sshow grestore } ! if ! } forall ! Ratio dup scale ! } repeat showpage diff -rc2N gs241/ansi2knr.c gs25/ansi2knr.c *** gs241/ansi2knr.c Fri Apr 26 05:09:54 1991 --- gs25/ansi2knr.c Tue Apr 28 16:36:58 1992 *************** *** 51,56 **** char *argv[]; { FILE *in, *out; ! #define bufsize 500 /* arbitrary size */ ! char buf[bufsize]; char *line; switch ( argc ) --- 51,56 ---- char *argv[]; { FILE *in, *out; ! #define bufsize 5000 /* arbitrary size */ ! char *buf; char *line; switch ( argc ) *************** *** 74,77 **** --- 74,78 ---- } fprintf(out, "#line 1 \"%s\"\n", argv[1]); + buf = malloc(bufsize); line = buf; while ( fgets(line, (unsigned)(buf + bufsize - line), in) != NULL ) *************** *** 83,87 **** case -1: /* maybe the start of a function */ line = buf + strlen(buf); ! continue; default: /* not a function */ fputs(buf, out); --- 84,90 ---- case -1: /* maybe the start of a function */ line = buf + strlen(buf); ! if ( line != buf + (bufsize - 1) ) /* overflow check */ ! continue; ! /* falls through */ default: /* not a function */ fputs(buf, out); *************** *** 91,94 **** --- 94,98 ---- } if ( line != buf ) fputs(buf, out); + free(buf); fclose(out); fclose(in); diff -rc2N gs241/ansihead.mak gs25/ansihead.mak *** gs241/ansihead.mak Wed Mar 25 10:24:08 1992 --- gs25/ansihead.mak Sat Aug 1 03:07:54 1992 *************** *** 26,34 **** # ------ Generic options ------ # # Define the default directory/ies for the runtime # initialization and font files. Separate multiple directories with a :. - # `pwd` means use the directory in which the 'make' is being done. ! GS_LIB_DEFAULT=`pwd`:`pwd`/fonts # Define the name of the Ghostscript initialization file. --- 26,46 ---- # ------ Generic options ------ # + # Define the installation commands and target directories for + # executables and files. Only relevant to `make install'. + + INSTALL = install -c + INSTALL_PROGRAM = $(INSTALL) -m 775 + INSTALL_DATA = $(INSTALL) -m 664 + + prefix = /usr/local + exec_prefix = $(prefix) + bindir = $(exec_prefix)/bin + datadir = $(prefix)/lib + gsdatadir = $(datadir)/ghostscript + # Define the default directory/ies for the runtime # initialization and font files. Separate multiple directories with a :. ! GS_LIB_DEFAULT=$(gsdatadir):$(gsdatadir)/fonts # Define the name of the Ghostscript initialization file. *************** *** 82,85 **** --- 94,99 ---- # This can be null if handled in some other way (e.g., the files are # in /usr/include, or the directory is supplied by an environment variable). + # Note that x_.h expects to find the header files in $(XINCLUDE)/X11, + # not in $(XINCLUDE). XINCLUDE=-I/usr/local/X/include *************** *** 89,103 **** XLIBDIRS=-L/usr/local/X/lib - - # Define the installation commands and target directories for - # executables and files. Only relevant to `make install'. - - INSTALL = install -c - INSTALL_PROGRAM = $(INSTALL) -m 775 - INSTALL_DATA = $(INSTALL) -m 664 - - prefix = /usr/local - bindir = $(prefix)/bin - libdir = $(prefix)/lib/ghostscript # ------ Devices and features ------ # --- 103,106 ---- diff -rc2N gs241/bcwin.mak gs25/bcwin.mak *** gs241/bcwin.mak --- gs25/bcwin.mak Sat Aug 15 11:10:54 1992 *************** *** 0 **** --- 1,246 ---- + # Copyright (C) 1989, 1992 Aladdin Enterprises. All rights reserved. + # Distributed by Free Software Foundation, Inc. + # + # This file is part of Ghostscript. + # + # Ghostscript is distributed in the hope that it will be useful, but + # WITHOUT ANY WARRANTY. No author or distributor accepts responsibility + # to anyone for the consequences of using it or for whether it serves any + # particular purpose or works at all, unless he says so in writing. Refer + # to the Ghostscript General Public License for full details. + # + # Everyone is granted permission to copy, modify and redistribute + # Ghostscript, but only under the conditions described in the Ghostscript + # General Public License. A copy of this license is supposed to have been + # given to you along with Ghostscript so you can know your rights and + # responsibilities. It should be in a file named COPYING. Among other + # things, the copyright notice and this notice must be preserved on all + # copies. + + # makefile for Ghostscript, MS-Windows 3.n/Borland C++ 3.0 or 3.1 platform. + + # ------------------------------- Options ------------------------------- # + + ###### This section is the only part of the file you should need to edit. + + # ------ Generic options ------ # + + # Define the default directory/ies for the runtime + # initialization and font files. Separate multiple directories with \;. + # Use / to indicate directories, not a single \. + + GS_LIB_DEFAULT=c:/gs\;c:/gs/fonts + + # Define the name of the Ghostscript initialization file. + # (There is no reason to change this.) + + GS_INIT=gs_init.ps + + # Choose generic configuration options. + + # Setting DEBUG=1 includes debugging features (-Z switch) in the code. + # Code runs substantially slower even if no debugging switches are set, + # and also takes about another 25K of memory. + + DEBUG=0 + + # Setting TDEBUG=1 includes symbol table information for the Borland debugger. + # No execution time or space penalty, just larger .OBJ and .EXE files + # and slower linking. + + TDEBUG=0 + + # Setting NOPRIVATE=1 makes private (static) procedures and variables public, + # so they are visible to the debugger and profiler. + # No execution time or space penalty, just larger .OBJ and .EXE files. + + NOPRIVATE=0 + + # ------ Platform-specific options ------ # + + # If you don't have an assembler, set USE_ASM=0. Otherwise, set USE_ASM=1, + # and set ASM to the name of the assembler you are using. This can be + # a full path name if you want. Normally it will be masm or tasm. + + USE_ASM=1 + ASM=tasm + + # Define the drive, directory, and compiler name for the Turbo C files. + # COMP is the compiler name (tcc for Turbo C++, bcc for Borland C++). + # COMPDIR contains the compiler and linker (normally \bc\bin). + # INCDIR contains the include files (normally \bc\include). + # LIBDIR contains the library files (normally \bc\lib). + # Note that these prefixes are always followed by a \, + # so if you want to use the current directory, use an explicit '.'. + + COMP=bcc + COMPDIR=c:\bc\bin + INCDIR=c:\bc\include + LIBDIR=c:\bc\lib + + # Windows 3.n requires a 286 CPU or higher. + + CPU_TYPE=286 + + # Don't rely on FPU for Windows. + + FPU_TYPE=0 + + # ---------------------------- End of options ---------------------------- # + + # Swapping `make' out of memory makes linking much faster. + + .swap + + # Define the platform name. + + PLATFORM=bcwin_ + + # Define the name of the makefile -- used in dependencies. + + MAKEFILE=bcwin.mak + + # Define the ANSI-to-K&R dependency. Turbo C accepts ANSI syntax, + # but we need to preconstruct ccf.tr to get around the limit on + # the maximum length of a command line. + + AK=ccf.tr + + # Define the compilation flags for an 80286. + # This is void because we handle -2 and -3 in ccf.tr (see below). + + F286= + + # Figure out which version of Borland C++ we are running. + # In the MAKE program that comes with Borland C++ 2.0, __MAKE__ is 0x300; + # in the MAKE that comes with Borland C++ 3.0 and 3.1, it is 0x360. + # We care because 3.0 has additional optimization features. + # There are also some places below where we distinguish BC++ 3.1 from 3.0 + # by testing whether $(INCDIR)\win30.h exists (true in 3.1, false in 3.0). + + EXIST_BC3_1=exist $(INCDIR)\win30.h + + !if $(__MAKE__) >= 0x360 + CO=-Obe -Z + !else + CO=-O + !endif + + !include "tccommon.mak" + + # Define the compilation flags. + + !if $(NOPRIVATE) + CP=-DNOPRIVATE + !else + CP= + !endif + + !if $(DEBUG) | $(TDEBUG) + CS=-N + !else + CS= + !endif + + !if $(DEBUG) + CD=-DDEBUG + !else + CD= + !endif + + !if $(TDEBUG) + CT=-v + LCT=/v + !else + CT=-y + LCT=/m /l + !endif + + GENOPT=$(CP) $(CS) $(CD) $(CT) + + CCFLAGS=$(GENOPT) $(PLATOPT) $(FPFLAGS) -m$(MM) + CC=$(COMPDIR)\$(COMP) @ccf.tr + CCC=$(CC) -W $(CO) -c + CCD=$(CC) -W -O -c + CC0=$(CC) -W -c + CCINT=$(CC) -W -c + + .c.obj: + $(CCC) { $<} + + # ------ Devices and features ------ # + + # Choose the language feature(s) to include. See gs.mak for details. + # Since Ghostscript runs in enhanced mode, we include a fair number + # of drivers, but we can't exceed 64K of static data. + + FEATURE_DEVS= + + # Choose the device(s) to include. See devs.mak for details. + + DEVICE_DEVS=mswin.dev epson.dev bj10e.dev paintjet.dev + DEVICE_DEVS2=deskjet.dev djet500.dev laserjet.dev ljetplus.dev ljet2p.dev ljet3.dev + DEVICE_DEVS4=gifmono.dev gif8.dev pcxmono.dev pcx16.dev pcx256.dev bit.dev + !include "gs.mak" + !include "devs.mak" + + # Build the compiler response file depending on the selected options. + + ccf.tr: $(MAKEFILE) makefile + echo -2 -a -d -r -G -N -X -I$(INCDIR) $(CCFLAGS) -DCHECK_INTERRUPTS >ccf.tr + !if $(CPU_TYPE) > 286 + echo -3 -a -d -r -G -N -X -I$(INCDIR) $(CCFLAGS) -DCHECK_INTERRUPTS >_temp_ + if $(EXIST_BC3_1) copy _temp_ ccf.tr + !endif + + # -------------------------------- Library -------------------------------- # + + # The Turbo/Borland C(++), Microsoft Windows platform + + bcwin__=gp_mswin.$(OBJ) gp_msdos.$(OBJ) + bcwin_.dev: $(bcwin__) + $(SHP)gssetmod bcwin_ $(bcwin__) + + gp_mswin.$(OBJ): gp_mswin.c gp_mswin.h $(memory__h) $(string__h) \ + $(gx_h) $(gp_h) $(gpcheck_h) $(gserrors_h) $(gxdevice_h) + + gp_msdos.$(OBJ): gp_msdos.c $(dos__h) $(string__h) $(gx_h) $(gp_h) + + # ----------------------------- Main program ------------------------------ # + + BEGINFILES=gs.res gs*.ico + + iutilasm.$(OBJ): iutilasm.asm + + # Get around the fact that the DOS shell has a rather small limit on + # the length of a command line. (sigh) + + LIBCTR=libc$(MM).tr + + $(LIBCTR): $(MAKEFILE) makefile + echo $(LIBDIR)\import $(LIBDIR)\mathw$(MM) $(LIBDIR)\cw$(MM) >$(LIBCTR) + + LIBDOS=$(LIB) obj.tr + + # Interpreter main program + + ICONS=gsgraph.ico gstext.ico + + GS_ALL=gs.$(OBJ) $(INT) $(INTASM) gsmain.$(OBJ)\ + $(LIBDOS) $(LIBCTR) obj.tr lib.tr gs.res gs.def $(ICONS) + + # Make the icons from their text form. + + gsgraph.ico: gsgraph.icx echogs$(XE) + echogs -wb gsgraph.ico -n -X -r gsgraph.icx + + gstext.ico: gstext.icx echogs$(XE) + echogs -wb gstext.ico -n -X -r gstext.icx + + gs.res: gs.rc gp_mswin.h $(ICONS) + $(COMPDIR)\rc -i$(INCDIR) -r gs + + gs.exe: $(GS_ALL) + tlink $(LCT) /Twe $(LIBDIR)\c0w$(MM) @obj.tr $(INTASM) @gs.tr ,gs,gs,@lib.tr @$(LIBCTR),gs.def + if $(EXIST_BC3_1) $(COMPDIR)\rc -30 -i$(INCDIR) gs + if not $(EXIST_BC3_1) $(COMPDIR)\rc -i$(INCDIR) gs diff -rc2N gs241/bdftops.ps gs25/bdftops.ps *** gs241/bdftops.ps Sat Feb 1 16:19:40 1992 --- gs25/bdftops.ps Sat Jul 25 17:45:22 1992 *************** *** 29,39 **** envBDF begin % "Import" the font-writing package. (wrfont.ps) run - % Define lenIV (the number of initial random bytes in the encoded outlines). - % This should be zero, but we set it to 4 for compatibility with PostScript. - /lenIV 4 def - % Invert the StandardEncoding vector. 256 dict dup begin --- 29,39 ---- envBDF begin + % "Import" the image-to-path package. + % This also brings in the Type 1 opcodes (type1ops.ps). + (impath.ps) run + % "Import" the font-writing package. (wrfont.ps) run % Invert the StandardEncoding vector. 256 dict dup begin *************** *** 142,157 **** /daggerdbl [/bar /equal] dicttomark /accentedchars exch def - - % Define the Type 1 opcodes we care about. - /c_callsubr 10 def /s_callsubr <0a> def - /c_return 11 def - /c_escape 12 def - /ce_seac 6 def /s_seac <0c06> def - /ce_sbw 7 def /s_sbw <0c07> def - /ce_setcurrentpoint 33 def /s_setcurrentpoint <0c21> def - /c_hsbw 13 def /s_hsbw <0d> def - /c_endchar 14 def /s_endchar <0e> def - /c_hmoveto 22 def - /s_setcurrentpoint_hmoveto s_setcurrentpoint <8b16> concatstrings def % ------ BDF file parsing utilities ------ % --- 142,145 ---- diff -rc2N gs241/bfont.h gs25/bfont.h *** gs241/bfont.h --- gs25/bfont.h Sat Apr 25 07:16:44 1992 *************** *** 0 **** --- 1,36 ---- + /* Copyright (C) 1992 Aladdin Enterprises. All rights reserved. + Distributed by Free Software Foundation, Inc. + + This file is part of Ghostscript. + + Ghostscript is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY. No author or distributor accepts responsibility + to anyone for the consequences of using it or for whether it serves any + particular purpose or works at all, unless he says so in writing. Refer + to the Ghostscript General Public License for full details. + + Everyone is granted permission to copy, modify and redistribute + Ghostscript, but only under the conditions described in the Ghostscript + General Public License. A copy of this license is supposed to have been + given to you along with Ghostscript so you can know your rights and + responsibilities. It should be in a file named COPYING. Among other + things, the copyright notice and this notice must be preserved on all + copies. */ + + /* bfont.h */ + /* Internal routines and data needed for building fonts */ + #include "font.h" + + /* In zfont.c */ + extern ref name_FID; + extern ref name_FontMatrix; + extern int add_FID(P2(ref *pfdict, gs_font *pfont)); + + /* In zfont2.c */ + extern ref name_UniqueID; + extern int build_gs_font(P4(os_ptr, gs_font **, font_type, const ref *)); + extern int build_gs_simple_font(P4(os_ptr, gs_font **, font_type, + const ref *)); + extern int font_int_param(P6(const ref *pdict, const ref *pname, + int minval, int maxval, + int defaultval, int *pvalue)); diff -rc2N gs241/cc-head.mak gs25/cc-head.mak *** gs241/cc-head.mak Fri Apr 10 05:46:10 1992 --- gs25/cc-head.mak Sat Aug 1 03:07:00 1992 *************** *** 26,34 **** # ------ Generic options ------ # # Define the default directory/ies for the runtime # initialization and font files. Separate multiple directories with a :. - # `pwd` means use the directory in which the 'make' is being done. ! GS_LIB_DEFAULT=`pwd`:`pwd`/fonts # Define the name of the Ghostscript initialization file. --- 26,46 ---- # ------ Generic options ------ # + # Define the installation commands and target directories for + # executables and files. Only relevant to `make install'. + + INSTALL = install -c + INSTALL_PROGRAM = $(INSTALL) -m 775 + INSTALL_DATA = $(INSTALL) -m 664 + + prefix = /usr/local + exec_prefix = $(prefix) + bindir = $(exec_prefix)/bin + datadir = $(prefix)/lib + gsdatadir = $(datadir)/ghostscript + # Define the default directory/ies for the runtime # initialization and font files. Separate multiple directories with a :. ! GS_LIB_DEFAULT=$(gsdatadir):$(gsdatadir)/fonts # Define the name of the Ghostscript initialization file. *************** *** 78,81 **** --- 90,95 ---- # This can be null if handled in some other way (e.g., the files are # in /usr/include, or the directory is supplied by an environment variable). + # Note that x_.h expects to find the header files in $(XINCLUDE)/X11, + # not in $(XINCLUDE). XINCLUDE=-I/usr/local/X/include *************** *** 85,99 **** XLIBDIRS=-L/usr/local/X/lib - - # Define the installation commands and target directories for - # executables and files. Only relevant to `make install'. - - INSTALL = install -c - INSTALL_PROGRAM = $(INSTALL) -m 775 - INSTALL_DATA = $(INSTALL) -m 664 - - prefix = /usr/local - bindir = $(prefix)/bin - libdir = $(prefix)/lib/ghostscript # ------ Devices and features ------ # --- 99,102 ---- diff -rc2N gs241/ccfont.h gs25/ccfont.h *** gs241/ccfont.h Wed Apr 8 10:15:30 1992 --- gs25/ccfont.h Mon Jun 1 02:21:04 1992 *************** *** 23,31 **** /* Define type-specific refs for initializing arrays. */ #define ref_(t) struct { struct tas_s tas; t value; } ! typedef struct { short len; char _ds *str; } charray; typedef struct { byte encx, charx; } charindex; #define array_v(n,p,ea)\ ! { {(t_array< + # define inport(px) inpw(px) # define inportb(px) inp(px) + # define outport(px,b) outpw(px,b) # define outportb(px,b) outp(px,b) # define enable() _enable() diff -rc2N gs241/dparam.h gs25/dparam.h *** gs241/dparam.h --- gs25/dparam.h Sun Jun 21 10:49:20 1992 *************** *** 0 **** --- 1,39 ---- + /* Copyright (C) 1992 Aladdin Enterprises. All rights reserved. + Distributed by Free Software Foundation, Inc. + + This file is part of Ghostscript. + + Ghostscript is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY. No author or distributor accepts responsibility + to anyone for the consequences of using it or for whether it serves any + particular purpose or works at all, unless he says so in writing. Refer + to the Ghostscript General Public License for full details. + + Everyone is granted permission to copy, modify and redistribute + Ghostscript, but only under the conditions described in the Ghostscript + General Public License. A copy of this license is supposed to have been + given to you along with Ghostscript so you can know your rights and + responsibilities. It should be in a file named COPYING. Among other + things, the copyright notice and this notice must be preserved on all + copies. */ + + /* dparam.h */ + /* Interface to idparam.c */ + + #ifndef gs_matrix_DEFINED + # define gs_matrix_DEFINED + typedef struct gs_matrix_s gs_matrix; + #endif + + int dict_bool_param(P4(const ref *pdict, const ref *pname, + int defaultval, int *pvalue)); + int dict_int_param(P6(const ref *pdict, const ref *pname, + int minval, int maxval, int defaultval, int *pvalue)); + int dict_float_param(P4(const ref *pdict, const ref *pname, + floatp defaultval, float *pvalue)); + int dict_int_array_param(P4(const ref *pdict, const ref *pname, + uint maxlen, int *ivec)); + int dict_float_array_param(P5(const ref *pdict, const ref *pname, + uint maxlen, float *fvec, float *defaultvec)); + int dict_matrix_param(P3(const ref *pdict, const ref *pname, + gs_matrix *pmat)); diff -rc2N gs241/drivers.doc gs25/drivers.doc *** gs241/drivers.doc Fri Feb 28 14:37:50 1992 --- gs25/drivers.doc Sat Aug 15 05:28:38 1992 *************** *** 134,138 **** structure, or add procedures, you must change the following places: ! - This document and history.doc (if you want to keep the documentation up to date). - The definition of gx_device_common and/or the procedures --- 134,138 ---- structure, or add procedures, you must change the following places: ! - This document and NEWS (if you want to keep the documentation up to date). - The definition of gx_device_common and/or the procedures *************** *** 282,286 **** * do word-oriented operations on them if you're on a little-endian * platform like the Intel 80x86 or VAX). Each scan line must start on ! * a (32-bit) word boundary, and hence must be is padded to a word boundary, * although this should rarely be of concern, since the raster and width * are specified individually. The first scan line corresponds to y=0 --- 282,286 ---- * do word-oriented operations on them if you're on a little-endian * platform like the Intel 80x86 or VAX). Each scan line must start on ! * a (32-bit) word boundary, and hence is padded to a word boundary, * although this should rarely be of concern, since the raster and width * are specified individually. The first scan line corresponds to y=0 *************** *** 302,308 **** ******** ! All the procedures that return int results return 0 on success, or -1 on ! invalid arguments. Most procedures are optional. If a device doesn't supply an optional procedure proc, the entry in the procedure structure should be --- 302,333 ---- ******** ! All the procedures that return int results return 0 on success, or an ! appropriate negative error code in the case of error conditions. The ! error codes are defined in gserrors.h. The relevant ones for drivers ! are as follows: + gs_error_invalidfileaccess + An attempt to open a file failed. + + gs_error_limitcheck + An otherwise valid parameter value was too large for + the implementation. + + gs_error_rangecheck + A parameter was outside the valid range. + + gs_error_VMerror + An attempt to allocate memory failed. (If this + happens, the procedure should release all memory it + allocated before it returns.) + + If a driver does return an error, it should use the return_error + macro rather than a simple return statement, e.g., + + return_error(gs_error_VMerror); + + This macro is defined in gx.h, which is automatically included by + gdevprn.h but not by gserrors.h. + Most procedures are optional. If a device doesn't supply an optional procedure proc, the entry in the procedure structure should be *************** *** 405,409 **** the next is always passed as an explicit argument. ! int (*copy_mono)(P11(gx_device *, unsigned char *data, int data_x, int raster, gx_bitmap_id id, int x, int y, int width, int height, gx_color_index color0, gx_color_index color1)) --- 430,434 ---- the next is always passed as an explicit argument. ! int (*copy_mono)(P11(gx_device *, const unsigned char *data, int data_x, int raster, gx_bitmap_id id, int x, int y, int width, int height, gx_color_index color0, gx_color_index color1)) *************** *** 424,428 **** so implementing it efficiently is very important. ! int (*tile_rectangle)(P10(gx_device *, gx_bitmap *tile, int x, int y, int width, int height, gx_color_index color0, gx_color_index color1, --- 449,453 ---- so implementing it efficiently is very important. ! int (*tile_rectangle)(P10(gx_device *, const gx_bitmap *tile, int x, int y, int width, int height, gx_color_index color0, gx_color_index color1, *************** *** 448,456 **** sometimes called "chunky" or "Z" format). The number of bits per pixel is given by the color_info.depth parameter in the device structure: the legal ! values are 1, 2, 4, 8, 16, 24, or 32. (****** 2 AND 4 ARE NOT SUPPORTED ! YET ******.) The pixel values are device color codes (i.e., whatever it ! is that map_rgb_color returns). ! int (*copy_color)(P9(gx_device *, unsigned char *data, int data_x, int raster, gx_bitmap_id id, int x, int y, int width, int height)) --- 473,480 ---- sometimes called "chunky" or "Z" format). The number of bits per pixel is given by the color_info.depth parameter in the device structure: the legal ! values are 1, 2, 4, 8, 16, 24, or 32. The pixel values are device color ! codes (i.e., whatever it is that map_rgb_color returns). ! int (*copy_color)(P9(gx_device *, const unsigned char *data, int data_x, int raster, gx_bitmap_id id, int x, int y, int width, int height)) *************** *** 517,521 **** Set the properties of the device from the property list at plist. ! Return 0 if everything was OK, -1 if some property had an invalid type or ! out-of-range value. See gsprops.h for more details, gx_default_put_props ! in gsdevice.c for an example. --- 541,546 ---- Set the properties of the device from the property list at plist. ! Return 0 if everything was OK, an error code ! (gs_error_undefined/typecheck/rangecheck/limitcheck) if some property had ! an invalid type or out-of-range value. See gsprops.h for more details, ! gx_default_put_props in gsdevice.c for an example. diff -rc2N gs241/dstack.h gs25/dstack.h *** gs241/dstack.h Thu Apr 16 12:42:36 1992 --- gs25/dstack.h Sat Jun 13 03:25:12 1992 *************** *** 30,38 **** /* Define the dictionary stack and the standard dictionaries. */ extern ref dstack[]; #define systemdict (dstack[0]) ! #define userdict (dstack[1]) /* Define the dictionary stack pointers. */ typedef ref _ds *ds_ptr; extern ds_ptr dsp, dstop; --- 30,40 ---- /* Define the dictionary stack and the standard dictionaries. */ extern ref dstack[]; + extern uint min_dstack_size; /* # of permanent entries */ #define systemdict (dstack[0]) ! #define userdict (dstack[min_dstack_size - 1]) /* Define the dictionary stack pointers. */ typedef ref _ds *ds_ptr; + typedef const ref _ds *const_ds_ptr; extern ds_ptr dsp, dstop; *************** *** 41,43 **** /* Return the pointer to the value slot. */ /* If the name isn't found, just return 0. */ ! extern ref *dict_find_name(P1(ref *pname)); --- 43,46 ---- /* Return the pointer to the value slot. */ /* If the name isn't found, just return 0. */ ! extern ref *dict_find_name_by_index(P1(uint nidx)); ! #define dict_find_name(pnref) dict_find_name_by_index(name_index(pnref)) diff -rc2N gs241/echogs.c gs25/echogs.c *** gs241/echogs.c --- gs25/echogs.c Sun Jul 12 06:33:22 1992 *************** *** 0 **** --- 1,166 ---- + /* Copyright (C) 1992 Aladdin Enterprises. All rights reserved. + Distributed by Free Software Foundation, Inc. + + This file is part of Ghostscript. + + Ghostscript is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY. No author or distributor accepts responsibility + to anyone for the consequences of using it or for whether it serves any + particular purpose or works at all, unless he says so in writing. Refer + to the Ghostscript General Public License for full details. + + Everyone is granted permission to copy, modify and redistribute + Ghostscript, but only under the conditions described in the Ghostscript + General Public License. A copy of this license is supposed to have been + given to you along with Ghostscript so you can know your rights and + responsibilities. It should be in a file named COPYING. Among other + things, the copyright notice and this notice must be preserved on all + copies. */ + + /* echogs.c */ + /* 'echo'-like utility */ + #include + #include + #include + + /* + * Usage: + echogs [-w[b] file | -a[b] file] [-n] + (-x hexstring | -q string | -s | -i | -r file)* [-] string* + * Echoes string(s), or the binary equivalent of hexstring(s). + * If -w, writes to file; if -a, appends to file; if neither, + * writes to stdout. -wb and -ab open the file in binary mode. + * If -n, does not append a newline to the output. -s writes a space. + * -i means read from stdin, treating each line as an argument. + * -r means read from a named file in the same way. + * -X means treat any following literals as hex rather than string data. + * - alone means treat the rest of the line as literal data, + * even if the first string begins with a -. + * Inserts spaces automatically between the trailing strings, + * but nowhere else; in particular, + echogs -q a b + * writes 'ab', in contrast to + echogs -q a -s b + * which writes 'a b'. + * + * This program exists solely to get around omissions, problems, and + * incompatibilities in the various shells and utility environments + * that Ghostscript must deal with. Don't count on it staying the same + * from one Ghostscript release to another! + */ + + main(argc, argv) + int argc; + char *argv[]; + { FILE *out = stdout; + FILE *in; + char *fmode; + char *fname = 0; + int newline = 1; + int interact = 0; + #define LINESIZE 1000 + char line[LINESIZE]; + char sw = 0, sp = 0, hexx = 0; + char **argp = argv + 1; + int nargs = argc - 1; + if ( nargs > 0 && (*argp)[0] == '-' && + ((*argp)[1] == 'w' || (*argp)[1] == 'a') + ) + { if ( nargs < 2 ) return 1; + fmode = *argp + 1; + fname = argp[1]; + argp += 2, nargs -= 2; + } + if ( nargs > 0 && !strcmp(*argp, "-n") ) + { newline = 0; + argp++, nargs--; + } + if ( fname != 0 ) + { out = fopen(fname, fmode); + if ( out == 0 ) return 1; + } + while ( 1 ) + { char *arg; + if ( interact ) + { if ( fgets(line, LINESIZE, in) == NULL ) + { interact = 0; + if ( in != stdin ) fclose(in); + continue; + } + /* Remove the terminating \n. */ + line[strlen(line) - 1] = 0; + arg = line; + } + else + { if ( nargs == 0 ) break; + arg = *argp; + argp++, nargs--; + } + if ( sw == 0 && arg[0] == '-' ) + { sp = 0; + switch ( arg[1] ) + { + case 'q': /* literal string */ + case 'r': /* read from a file */ + case 'x': /* hex string */ + sw = arg[1]; + break; + case 's': /* write a space */ + fputc(' ', out); + break; + case 'i': /* read interactively */ + interact = 1; + in = stdin; + break; + case 'X': /* treat literals as hex */ + hexx = 1; + break; + case 0: /* just '-' */ + sw = '-'; + break; + } + } + else + switch ( sw ) + { + case 0: + sw = '-'; + case '-': + if ( hexx ) goto xx; + if ( sp ) fputc(' ', out); + fputs(arg, out); + sp = 1; + break; + case 'q': + sw = 0; + fputs(arg, out); + break; + case 'r': + sw = 0; + in = fopen(arg, "r"); + if ( in == NULL ) exit(1); + interact = 1; + break; + case 'x': + xx: { char *xp; + unsigned int xchr = 1; + for ( xp = arg; *xp; xp++ ) + { char ch = *xp; + if ( !isxdigit(ch) ) return 1; + xchr <<= 4; + xchr += (isdigit(ch) ? ch - '0' : + (isupper(ch) ? tolower(ch) : ch) + - 'a' + 10); + if ( xchr >= 0x100 ) + { fputc(xchr & 0xff, out); + xchr = 1; + } + } + } sw = 0; + break; + } + } + if ( newline ) fputc('\n', out); + if ( out != stdout ) fclose(out); + return 0; + } diff -rc2N gs241/echoq gs25/echoq *** gs241/echoq Mon Sep 9 17:45:08 1991 --- gs25/echoq *************** *** 1,7 **** - # Figure out what we have to do to get a \ in the output of 'echo'. - # System V `echo' strips \s, but doesn't recognize -n; - # bsd `echo' does the opposite. Figure out which one we have. - echo -n >_temp_.echo - if ( test -s _temp_.echo ) ; then echo $* \\\\; fi - if ( test \! -s _temp_.echo ) ; then echo $* \\; fi - rm _temp_.echo --- 0 ---- diff -rc2N gs241/ega.c gs25/ega.c *** gs241/ega.c Wed Mar 25 10:08:52 1992 --- gs25/ega.c Fri Apr 24 02:42:52 1992 *************** *** 27,32 **** #include "gxdevice.h" ! /* Stuff in egaxxx.c */ extern struct gx_device_s gs_ega_device; float yDx = 35.0/48.0; /* aspect ratio */ --- 27,33 ---- #include "gxdevice.h" ! /* Stuff in gdevpcfb.c */ extern struct gx_device_s gs_ega_device; + #define the_device (&gs_ega_device) float yDx = 35.0/48.0; /* aspect ratio */ *************** *** 59,68 **** raster = (width + 7) >> 3; yskip = (height > 350 ? height - 350 : 0); ! ega_open(&gs_ega_device); for ( y = 0; y < height; y++ ) { fread(line, 1, raster, f); if ( y >= yskip ) ! ega_copy_mono(&gs_ega_device, line, 0, raster, ! 0, y - yskip, width, 1, white, black); } fclose(f); --- 60,70 ---- raster = (width + 7) >> 3; yskip = (height > 350 ? height - 350 : 0); ! (*the_device->procs->open_device)(&the_device); for ( y = 0; y < height; y++ ) { fread(line, 1, raster, f); if ( y >= yskip ) ! (*the_device->procs->copy_mono)(the_device, ! line, 0, raster, gx_no_bitmap_id, ! 0, y - yskip, width, 1, white, black); } fclose(f); *************** *** 70,74 **** else { /* Display all kinds of stuff */ ! ega_open(&gs_ega_device); if ( !kbhit() ) paint1(); if ( !kbhit() ) paint2(); --- 72,76 ---- else { /* Display all kinds of stuff */ ! (*the_device->procs->open_device)(the_device); if ( !kbhit() ) paint1(); if ( !kbhit() ) paint2(); *************** *** 78,82 **** } while ( !kbhit() ) ; ! ega_close(&gs_ega_device); } --- 80,84 ---- } while ( !kbhit() ) ; ! (*the_device->procs->close_device)(the_device); } *************** *** 87,90 **** --- 89,94 ---- int gx_default_sync_output() { return 0; } int gx_default_tile_rectangle() { return -1; } + int gx_default_get_props() { return 0; } + int gx_default_put_props() { return 0; } /* Display color samples */ *************** *** 96,111 **** for ( b = 0; b <= m; b++ ) { int x = r * 30, y = (g*(m+1)+b) * 24; ! gx_color_index color = ega_map_rgb_color(&gs_ega_device, r, g, b); ! static unsigned char map[12] = { ! 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, ! 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55 }; ! ega_fill_rectangle(&gs_ega_device, x, y, 21, 8, color); ! ega_copy_mono(&gs_ega_device, map, 0, 3, x, y + 8, 21, 4, white, color); ! ega_copy_mono(&gs_ega_device, map, 0, 3, x, y + 12, 21, 4, black, color); } { int c; for ( c = 0; c <= 15; c++ ) ! { ega_fill_rectangle(&gs_ega_device, 320+c*20, 0, 14, 11, (gx_color_index)c); } } --- 100,119 ---- for ( b = 0; b <= m; b++ ) { int x = r * 30, y = (g*(m+1)+b) * 24; ! gx_color_index color = ! (*the_device->procs->map_rgb_color)(the_device, ! (ushort)(r * 0xffffL / m), ! (ushort)(g * 0xffffL / m), ! (ushort)(b * 0xffffL / m)); ! static unsigned char map[16] = { ! 0xaa, 0xaa, 0xaa, 0, 0x55, 0x55, 0x55, 0, ! 0xaa, 0xaa, 0xaa, 0, 0x55, 0x55, 0x55, 0 }; ! (*the_device->procs->fill_rectangle)(the_device, x, y, 21, 8, color); ! (*the_device->procs->copy_mono)(the_device, map, 0, 4, gx_no_bitmap_id, x, y + 8, 21, 4, white, color); ! (*the_device->procs->copy_mono)(the_device, map, 0, 4, gx_no_bitmap_id, x, y + 12, 21, 4, black, color); } { int c; for ( c = 0; c <= 15; c++ ) ! { (*the_device->procs->fill_rectangle)(the_device, 320+c*20, 0, 14, 11, (gx_color_index)c); } } *************** *** 125,133 **** tile.data = pattern; tile.raster = 2; ! tile.size.x = 16; ! tile.size.y = 16; for ( i = 0; i < 5; i++ ) for ( j = 0; j < 5; j++ ) ! ega_tile_rectangle(&gs_ega_device, &tile, 212+i*44, 20+j*44, 32, 32, colors[i], colors[j]); } --- 133,142 ---- tile.data = pattern; tile.raster = 2; ! tile.size.x = tile.rep_width = 16; ! tile.size.y = tile.rep_height = 16; ! tile.id = gx_no_bitmap_id; for ( i = 0; i < 5; i++ ) for ( j = 0; j < 5; j++ ) ! (*the_device->procs->tile_rectangle)(the_device, &tile, 212+i*44, 20+j*44, 32, 32, colors[i], colors[j], 0, 0); } *************** *** 135,150 **** paint3() { static byte turkey[] = { ! 0x00,0x3b,0x00, 0x00,0x27,0x00, 0x00,0x24,0x80, ! 0x0e,0x49,0x40, 0x11,0x49,0x20, 0x14,0xb2,0x20, ! 0x3c,0xb6,0x50, 0x75,0xfe,0x88, 0x17,0xff,0x8c, ! 0x17,0x5f,0x14, 0x1c,0x07,0xe2, 0x38,0x03,0xc4, ! 0x70,0x31,0x82, 0xf8,0xed,0xfc, 0xb2,0xbb,0xc2, ! 0xbb,0x6f,0x84, 0x31,0xbf,0xc2, 0x18,0xea,0x3c, ! 0x0e,0x3e,0x00, 0x07,0xfc,0x00, 0x03,0xf8,0x00, ! 0x1e,0x18,0x00, 0x1f,0xf8,0x00 }; ! ega_fill_rectangle(&gs_ega_device, 0, 250, 30, 30, yellow); ! ega_copy_mono(&gs_ega_device, turkey, 0, 3, 0, 250, 24, 23, white, red); ! ega_copy_color(&gs_ega_device, turkey, 0, 3, 0, 280, 6, 23); } --- 144,159 ---- paint3() { static byte turkey[] = { ! 0x00,0x3b,0x00,0, 0x00,0x27,0x00,0, 0x00,0x24,0x80,0, ! 0x0e,0x49,0x40,0, 0x11,0x49,0x20,0, 0x14,0xb2,0x20,0, ! 0x3c,0xb6,0x50,0, 0x75,0xfe,0x88,0, 0x17,0xff,0x8c,0, ! 0x17,0x5f,0x14,0, 0x1c,0x07,0xe2,0, 0x38,0x03,0xc4,0, ! 0x70,0x31,0x82,0, 0xf8,0xed,0xfc,0, 0xb2,0xbb,0xc2,0, ! 0xbb,0x6f,0x84,0, 0x31,0xbf,0xc2,0, 0x18,0xea,0x3c,0, ! 0x0e,0x3e,0x00,0, 0x07,0xfc,0x00,0, 0x03,0xf8,0x00,0, ! 0x1e,0x18,0x00,0, 0x1f,0xf8,0x00,0 }; ! (*the_device->procs->fill_rectangle)(the_device, 0, 250, 30, 30, yellow); ! (*the_device->procs->copy_mono)(the_device, turkey, 0, 4, gx_no_bitmap_id, 0, 250, 24, 23, white, red); ! (*the_device->procs->copy_color)(the_device, turkey, 0, 4, gx_no_bitmap_id, 0, 280, 6, 23); } *************** *** 152,163 **** paint4() { static unsigned char box[] = ! { 0xff,0xff, 0xc0,0x0c, 0xc0,0x0c, 0xc0,0x0c, 0xff,0xff }; int i, j; ! ega_fill_rectangle(&gs_ega_device, 432 - 4, 20 - 4, 4 + 8 * 17 + 8, 4 + 8 * 17, green); for ( i = 0; i < 8; i++ ) for ( j = 0; j < 8; j++ ) ! ega_copy_mono(&gs_ega_device, box, i, 2, ! 432 + (j * 17) + i, 20 + (i * 17), j + 1, 5, black, red); } --- 161,172 ---- paint4() { static unsigned char box[] = ! { 0xff,0xff,0,0, 0xc0,0x0c,0,0, 0xc0,0x0c,0,0, 0xc0,0x0c,0,0, 0xff,0xff,0,0 }; int i, j; ! (*the_device->procs->fill_rectangle)(the_device, 432 - 4, 20 - 4, 4 + 8 * 17 + 8, 4 + 8 * 17, green); for ( i = 0; i < 8; i++ ) for ( j = 0; j < 8; j++ ) ! (*the_device->procs->copy_mono)(the_device, box, i, 4, ! gx_no_bitmap_id, 432 + (j * 17) + i, 20 + (i * 17), j + 1, 5, black, red); } *************** *** 177,181 **** int x = ox + kx * cos(theta); int y = oy + ky * sin(theta); ! ega_write_dot(&gs_ega_device, x, y, red); } /* Plot with 90 degree arcs */ --- 186,190 ---- int x = ox + kx * cos(theta); int y = oy + ky * sin(theta); ! ega_write_dot(the_device, x, y, red); } /* Plot with 90 degree arcs */ *************** *** 220,224 **** { int x = ((ax * t + bx) * t + cx) * t + x0; int y = ((ay * t + by) * t + cy) * t + y0; ! ega_write_dot(&gs_ega_device, x, y, color); t += dt; } --- 229,233 ---- { int x = ((ax * t + bx) * t + cx) * t + x0; int y = ((ay * t + by) * t + cy) * t + y0; ! ega_write_dot(the_device, x, y, color); t += dt; } diff -rc2N gs241/ega.tr gs25/ega.tr *** gs241/ega.tr Fri Dec 6 16:46:16 1991 --- gs25/ega.tr Fri Apr 24 02:17:04 1992 *************** *** 1 **** ! ega trace gdevpcfb gdevegaa,ega,ega, \ No newline at end of file --- 1 ---- ! ega gdevpcfb gdevegaa,ega,ega, \ No newline at end of file diff -rc2N gs241/errors.h gs25/errors.h *** gs241/errors.h Tue Apr 7 15:31:48 1992 --- gs25/errors.h Tue Jun 16 03:24:14 1992 *************** *** 110,111 **** --- 110,126 ---- # endif /* INCLUDE_ERROR_NAMES */ + + /* ------ Pseudo-errors used internally ------ */ + + /* Internal code for a fatal error. */ + /* gs_interpret also returns this for any non-zero quit. */ + #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) diff -rc2N gs241/estack.h gs25/estack.h *** gs241/estack.h Sat Apr 18 18:56:14 1992 --- gs25/estack.h Fri Apr 24 20:35:16 1992 *************** *** 28,34 **** ********************************/ typedef ref _ds *es_ptr; extern es_ptr esbot, esp, estop; /* ! * In the near future, we will cache the currentfile pointer * (i.e., `shallow-bind' it in Lisp terminology). The invariant is as * follows: either esfile points to the currentfile slot on the estack --- 28,35 ---- ********************************/ typedef ref _ds *es_ptr; + typedef const ref _ds *const_es_ptr; extern es_ptr esbot, esp, estop; /* ! * To improve performance, we cache the currentfile pointer * (i.e., `shallow-bind' it in Lisp terminology). The invariant is as * follows: either esfile points to the currentfile slot on the estack *************** *** 37,41 **** * whenever a routine pushes or pops anything on the estack, if the object * *might* be an executable file, set esfile to 0. - ****** NOT IMPLEMENTED YET ****** */ extern es_ptr esfile; --- 38,41 ---- diff -rc2N gs241/file.h gs25/file.h *** gs241/file.h Wed Apr 15 14:24:40 1992 --- gs25/file.h *************** *** 1,53 **** - /* Copyright (C) 1989, 1990, 1991 Aladdin Enterprises. All rights reserved. - Distributed by Free Software Foundation, Inc. - - This file is part of Ghostscript. - - Ghostscript is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY. No author or distributor accepts responsibility - to anyone for the consequences of using it or for whether it serves any - particular purpose or works at all, unless he says so in writing. Refer - to the Ghostscript General Public License for full details. - - Everyone is granted permission to copy, modify and redistribute - Ghostscript, but only under the conditions described in the Ghostscript - General Public License. A copy of this license is supposed to have been - given to you along with Ghostscript so you can know your rights and - responsibilities. It should be in a file named COPYING. Among other - things, the copyright notice and this notice must be preserved on all - copies. */ - - /* file.h */ - /* Common declarations for zfile.c and zfileio.c */ - /* Requires stream.h */ - - /* File objects store a pointer to a stream in value.pfile. */ - /* A file object is valid if its buffer size is non-zero. */ - /* The value.pfile of an invalid file object points to an invalid stream. */ - #define fptr(pref) (pref)->value.pfile - #define make_file(pref,a,s)\ - make_tav(pref,t_file,a,pfile,s) - - /* The standard files. 0 is %stdin, 1 is %stdout. */ - extern stream std_files[]; - /* An invalid file. */ - extern stream invalid_file_entry; - - /* Macros for checking file validity */ - #define check_file_access(svar,op,acc)\ - { svar = fptr(op); /* do first, acc may refer to it */\ - if ( !(acc) ) return e_invalidaccess;\ - } - #define check_file_ref(svar,op,acc)\ - { if ( !r_has_type(op, t_file) ) return e_typecheck;\ - check_file_access(svar,op,acc);\ - } - #define check_file(svar,op) check_file_ref(svar,op,s_is_valid(svar)) - #define check_read_file(svar,op)\ - { check_read_type(*(op), t_file);\ - check_file_access(svar,op,s_is_reading(svar));\ - } - #define check_write_file(svar,op)\ - { check_write_type(*(op), t_file);\ - check_file_access(svar,op,s_is_writing(svar));\ - } --- 0 ---- diff -rc2N gs241/files.h gs25/files.h *** gs241/files.h --- gs25/files.h Mon Jul 20 02:07:58 1992 *************** *** 0 **** --- 1,56 ---- + /* Copyright (C) 1989, 1992 Aladdin Enterprises. All rights reserved. + Distributed by Free Software Foundation, Inc. + + This file is part of Ghostscript. + + Ghostscript is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY. No author or distributor accepts responsibility + to anyone for the consequences of using it or for whether it serves any + particular purpose or works at all, unless he says so in writing. Refer + to the Ghostscript General Public License for full details. + + Everyone is granted permission to copy, modify and redistribute + Ghostscript, but only under the conditions described in the Ghostscript + General Public License. A copy of this license is supposed to have been + given to you along with Ghostscript so you can know your rights and + responsibilities. It should be in a file named COPYING. Among other + things, the copyright notice and this notice must be preserved on all + copies. */ + + /* files.h */ + /* Common declarations for zfile.c and zfileio.c */ + /* Requires stream.h */ + + /* File objects store a pointer to a stream in value.pfile. */ + /* A file object is valid if its "size" matches the read_id or write_id */ + /* (as appropriate) in the stream it points to. This arrangement */ + /* allows us to detect closed files reliably, while allowing us to */ + /* reuse closed streams for new files. */ + #define fptr(pref) (pref)->value.pfile + #define make_file(pref,a,id,s)\ + make_tasv(pref,t_file,a,id,pfile,s) + + /* The standard files. 0 is %stdin, 1 is %stdout. */ + extern stream std_files[]; + /* An invalid file. */ + extern stream invalid_file_entry; + + /* Macros for checking file validity */ + #define check_file_access(svar,op,acc)\ + { svar = fptr(op); /* do first, acc may refer to it */\ + if ( !(acc) ) return e_invalidaccess;\ + } + #define check_file_ref(svar,op,acc)\ + { if ( !r_has_type(op, t_file) ) return e_typecheck;\ + check_file_access(svar,op,acc);\ + } + #define check_file(svar,op)\ + check_file_ref(svar, op, (svar->read_id | svar->write_id) == r_size(op)) + #define check_read_file(svar,op)\ + { check_read_type(*(op), t_file);\ + check_file_access(svar, op, svar->read_id == r_size(op));\ + } + #define check_write_file(svar,op)\ + { check_write_type(*(op), t_file);\ + check_file_access(svar, op, svar->write_id == r_size(op));\ + } diff -rc2N gs241/font2c.ps gs25/font2c.ps *** gs241/font2c.ps Wed Apr 8 10:41:38 1992 --- gs25/font2c.ps Tue Aug 11 05:52:14 1992 *************** *** 21,25 **** % Write out a Type 1 font as C code that can be linked with Ghostscript. % This even works on protected fonts, if you use the -dWRITESYSTEMDICT ! % switch in the command line. % Define the maximum string length that will get by the compiler. --- 21,26 ---- % Write out a Type 1 font as C code that can be linked with Ghostscript. % This even works on protected fonts, if you use the -dWRITESYSTEMDICT ! % switch in the command line. The code is reentrant and has no ! % external references, so it can be shared. % Define the maximum string length that will get by the compiler. *************** *** 61,65 **** { exch pop dup type dup /stringtype eq exch /arraytype eq or ! { getpa or } { pop pop a_all exit } ifelse --- 62,66 ---- { exch pop dup type dup /stringtype eq exch /arraytype eq or ! { getpa a_readonly and or } { pop pop a_all exit } ifelse *************** *** 70,78 **** % Keep track of executeonly and noaccess objects, % but don't let the protection actually take effect. systemdict wcheck - { /protected 1500 dict def } - { /protected null def } - ifelse % do first so // will work - systemdict wcheck { systemdict begin /executeonly --- 71,78 ---- % Keep track of executeonly and noaccess objects, % but don't let the protection actually take effect. + /protected % do first so // will work + systemdict wcheck { 1500 dict } { null } ifelse + def systemdict wcheck { systemdict begin /executeonly *************** *** 104,108 **** % Write a C string. Some compilers have unreasonably small limits on % the length of a string literal or the length of a line, so every place ! % that uses wcs or wcsl must either believe that the string is short, % or be prepared to use wcca instead. /wbx --- 104,108 ---- % Write a C string. Some compilers have unreasonably small limits on % the length of a string literal or the length of a line, so every place ! % that uses wcs must either know that the string is short, % or be prepared to use wcca instead. /wbx *************** *** 110,116 **** } bind def /wcst [ ! /wbx load 31 { dup } repeat ! /wb load 94 { dup } repeat ! /wbx load 128 { dup } repeat ] def ("\\) { wcst exch { (\\) ws wb } put } forall --- 110,116 ---- } bind def /wcst [ ! 32 { /wbx load } repeat ! 95 { /wb load } repeat ! 129 { /wbx load } repeat ] def ("\\) { wcst exch { (\\) ws wb } put } forall *************** *** 118,127 **** { (") ws { dup wcst exch get exec } forall (") ws } bind def - /wcsl % Write C string with length - { ({) ws dup length wt (,) ws wcs (}) ws - } bind def /can_wcs % Test if can use wcs { length max_wcs le } bind def % Write a C string as an array of character values. % We only need this because of line and literal length limitations. --- 118,127 ---- { (") ws { dup wcst exch get exec } forall (") ws } bind def /can_wcs % Test if can use wcs { length max_wcs le } bind def + /wncs % name -> C string + { wtstring cvs wcs + } bind def % Write a C string as an array of character values. % We only need this because of line and literal length limitations. *************** *** 135,142 **** } bind def ! % Write object protection attributes. /wpa { dup xcheck { (a_executable+) ws } if ! getpa prot_names exch get ws } bind def /wva --- 135,144 ---- } bind def ! % Write object protection attributes. Note that dictionaries are ! % the only objects that can be writable. /wpa { dup xcheck { (a_executable+) ws } if ! dup type /dicttype eq { getpa } { getpa a_readonly and } ifelse ! prot_names exch get ws } bind def /wva *************** *** 144,147 **** --- 146,151 ---- } bind def + % ------ Object writing ------ % + % Write a named object. Return true if this was possible. % Legal types are: boolean, integer, name, real, string, *************** *** 153,156 **** --- 157,211 ---- forall exch pop } bind def + /wnstring 128 string def + /wott 7 dict dup begin + /arraytype + { woatt + { aload pop 2 index 2 index isall + { exch pop exec exit } + { pop pop } + ifelse + } + forall + } bind def + /booleantype + { exch (static const ref_(ushort) ) ws wt ( = boolean_v\() ws + { (1) } { (0) } ifelse ws (\);) wl true + } bind def + /dicttype + { pop alldictdict exch known + } bind def + /integertype + { exch (static const ref_(long) ) ws wt ( = integer_v\() ws + wt (\);) wl true + } bind def + /nametype + { exch (static const ref_(const char *) ) ws wt ( = name_v\() ws + wnstring cvs dup length wt (,) ws wcs % OK, names are short + (\);) wl true + } bind def + /realtype + { exch (static const ref_(float) ) ws wt ( = real_v\() ws + wt (\);) wl true + } bind def + /stringtype + { dup can_wcs + { exch (static const ref_(const char *) ) ws wt ( = string_v\() ws + dup length wt (,) ws wcs (\);) wl true + } + { (static const char ) ws 1 index wt (_[] = ) ws wcca (;) wl + dup dup (static const ref_(const char *) ) ws wt + ( = string_v\(sizeof\() ws wt (_\),) ws wt (_\);) wl true + } + ifelse + } bind def + end def + /wo % name obj -> OK + { dup type wott exch known + { dup type wott exch get exec } + { pop pop false } + ifelse + } bind def + + % Write an array (called by wo). /wta % name wproc array -> { dup 4 1 roll *************** *** 160,164 **** (\)) ws (,\n) } ! forall pop pop (\n};\nstatic ref_(ref *) ) ws dup wt ( = array_v\() ws 1 index length wt (, ) ws wt (_array, ) ws wpa (\);) wl --- 215,219 ---- (\)) ws (,\n) } ! forall pop pop (\n};\nstatic const ref_(const ref *) ) ws dup wt ( = array_v\() ws 1 index length wt (, ) ws wt (_array, ) ws wpa (\);) wl *************** *** 167,175 **** % Integers { { type /integertype eq } ! { (static ref_(long) ) ws { (integer_v\() ws wt } exch wta true } } % Integers + reals { { type dup /integertype eq exch /realtype eq or } ! { (static ref_(float) ) ws { (real_v\() ws wt } exch wta true } } % Strings + nulls --- 222,230 ---- % Integers { { type /integertype eq } ! { (static const ref_(long) ) ws { (integer_v\() ws wt } exch wta true } } % Integers + reals { { type dup /integertype eq exch /realtype eq or } ! { (static const ref_(float) ) ws { (real_v\() ws wt } exch wta true } } % Strings + nulls *************** *** 185,189 **** { exch wtstring cvs (_) concatstrings a_name wtstring cvs exch concatstrings ! (static char ) ws dup ws ([] = ) ws exch wcca (;) wl } ifelse --- 240,244 ---- { exch wtstring cvs (_) concatstrings a_name wtstring cvs exch concatstrings ! (static const char ) ws dup ws ([] = ) ws exch wcca (;) wl } ifelse *************** *** 194,198 **** a_name exch % Now write the array itself ! (static ref_(char *) ) ws { dup null eq { pop (null_v\() ws } --- 249,253 ---- a_name exch % Now write the array itself ! (static const ref_(const char *) ) ws { dup null eq { pop (null_v\() ws } *************** *** 208,260 **** } ] def - /wnstring 128 string def - /wott 7 dict dup begin - /arraytype - { woatt - { aload pop 2 index 2 index isall - { exch pop exec exit } - { pop pop } - ifelse - } - forall - } bind def - /booleantype - { exch (static const ref_(ushort) ) ws wt ( = boolean_v\() ws - { (1) } { (0) } ifelse ws (\);) wl true - } bind def - /dicttype - { pop alldictdict exch known - } bind def - /integertype - { exch (static const ref_(long) ) ws wt ( = integer_v\() ws - wt (\);) wl true - } bind def - /nametype - { exch (static const ref_(const char *) ) ws wt ( = name_v\() ws - wnstring cvs dup length wt (,) ws wcs % OK, names are short - (\);) wl true - } bind def - /realtype - { exch (static const ref_(float) ) ws wt ( = real_v\() ws - wt (\);) wl true - } bind def - /stringtype - { dup can_wcs - { exch (static const ref_(const char *) ) ws wt ( = string_v\() ws - dup length wt (,) ws wcs (\);) wl true - } - { (static char ) ws 1 index wt (_[] = ) ws wcca (;) wl - dup dup (static const ref_(const char *) ) ws wt - ( = string_v\(sizeof\() ws wt (_\),) ws wt (_\);) wl true - } - ifelse - } bind def - end def - /wo % name obj -> OK - { dup type wott exch known - { dup type wott exch get exec } - { pop pop false } - ifelse - } bind def % Write a named dictionary. We assume the ref is already declared. --- 263,266 ---- *************** *** 268,277 **** ] dup (static const char _ds *str_keys_[] = {) wl ! { wtstring cvs wcs % OK, key names are short ! (,) wl } forall (0\n};) wl (static const ref _ds *values_[] = {\n) exch ! { exch ws ((const ref _ds *)&) ws wt (,\n) } forall pop (\n};) wl --- 274,285 ---- ] dup (static const char _ds *str_keys_[] = {) wl ! { wncs (,) wl % OK, key names are short } forall (0\n};) wl (static const ref _ds *values_[] = {\n) exch ! { exch ws ! % Fill in the real value for dictionaries later. ! dup alldictdict exch known { pop (static_null) } if ! ((const ref _ds *)&) ws wt (,\n) } forall pop (\n};) wl *************** *** 278,285 **** (\tstatic const cfont_dict_keys keys_ =) wl (\t { 0, 0, str_keys_, countof\(str_keys_\) - 1, 1, ) ws ! dup wpa (, ) ws wva ( };) wl ! (\tcode = cfont_ref_dict_create\(&) ws wt (, &keys_, &values_[0]\);) wl (\tif (code < 0) return code;) wl (}) wl } bind def --- 286,305 ---- (\tstatic const cfont_dict_keys keys_ =) wl (\t { 0, 0, str_keys_, countof\(str_keys_\) - 1, 1, ) ws ! dup wpa (, ) ws dup wva ( };) wl ! (\tcode = \(*pprocs->ref_dict_create\)\(&) ws 1 index wt (, &keys_, &values_[0]\);) wl (\tif (code < 0) return code;) wl + % Now fill in the values that reference dictionaries, + % which are created dynamically. + { pop dup alldictdict exch known + { (\tcode = \(*pprocs->dict_put\)\(&) ws 1 index wt + (, ) ws dup wncs (, &) ws wt (\);) wl + (\tif (code < 0) return code;) wl + } + { pop + } + ifelse + } + forall pop (}) wl } bind def *************** *** 341,345 **** dup wpa (, ) ws wva () wl (};) wl ! (\tcode = cfont_) ws ws (_dict_create\(&) ws ws (, &keys_, &values_[0]\);) wl (\tif ( code < 0 ) return code;) wl } bind def --- 361,365 ---- dup wpa (, ) ws wva () wl (};) wl ! (\tcode = \(*pprocs->) ws ws (_dict_create\)\(&) ws ws (, &keys_, &values_[0]\);) wl (\tif ( code < 0 ) return code;) wl } bind def *************** *** 356,373 **** % Invert the StandardEncoding and ISOLatin1Encoding vector. 512 dict begin ! 0 1 255 { dup ISOLatin1Encoding exch get exch 256 add def } bind for ! 0 1 255 { dup StandardEncoding exch get exch def } bind for currentdict end /decoding exch def ! /writefont % cfilename -> [writes the current font] ! { /cfname exch def ! /cfile cfname (w) file def ! /Font currentfont def ! Font /FontName get wtstring cvs ! dup length 1 sub 0 exch 1 exch { dup wtstring exch get 45 eq { wtstring exch 95 put } { pop } ifelse } ! for (font_) exch concatstrings ! /fontproc exch def Font /CharStrings get length dict /charmap exch def --- 376,397 ---- % Invert the StandardEncoding and ISOLatin1Encoding vector. 512 dict begin ! 0 1 255 { dup ISOLatin1Encoding exch get exch 256 add def } for ! 0 1 255 { dup StandardEncoding exch get exch def } for currentdict end /decoding exch def ! /makefontprocname % fontname -> procname ! { wtstring cvs ! dup length 1 sub -1 0 { dup wtstring exch get 45 eq { wtstring exch 95 put } { pop } ifelse } ! for ! } def ! ! /writefont % cfilename procname -> [writes the current font] ! { (gsf_) exch concatstrings ! /fontprocname exch def ! /cfname exch def ! /cfile cfname (w) file def ! /Font currentfont def Font /CharStrings get length dict /charmap exch def *************** *** 419,438 **** () wl } if ! (#include "ghost.h") wl (#include "ccfont.h") wl - (#include "oper.h") wl - (#include "errors.h") wl () wl ! % Write the operator prologue. ! (static int) wl (#ifdef __PROTOTYPES__) wl ! fontproc ws ((os_ptr op)) wl (#else) wl ! fontproc ws ((op) os_ptr op;) wl (#endif) wl ({\tint code;) wl alldictnames ! { (\tstatic ref ) ws ws (;) wl } forall --- 443,463 ---- () wl } if ! (#include "std.h") wl ! (#include "iref.h") wl (#include "ccfont.h") wl () wl ! % Write the procedure prologue. (#ifdef __PROTOTYPES__) wl ! (int) wl ! fontprocname ws ((const cfont_procs _ds *pprocs, ref *pfont)) wl (#else) wl ! (int) wl ! fontprocname ws ((pprocs, pfont) const cfont_procs _ds *pprocs; ref *pfont;) wl (#endif) wl ({\tint code;) wl + (\tstatic const ref_(long) static_null = null_v();) wl alldictnames ! { (\tref ) ws ws (;) wl } forall *************** *** 449,453 **** 1 add } forall pop ! (CharStrings) (string) CharStrings (charray) { ({sizeof\(cs) ws charmap exch get dup wt (\),cs) ws wt (}) ws --- 474,478 ---- 1 add } forall pop ! (CharStrings) (string) CharStrings (const_charray) { ({sizeof\(cs) ws charmap exch get dup wt (\),cs) ws wt (}) ws *************** *** 474,478 **** } forall pop (\n};) wl ! (\tcode = cfont_name_array_create\(&Encoding, str_elts_, countof\(str_elts_\)\);) wl (\tif (code < 0) return code;) wl (}) wl --- 499,503 ---- } forall pop (\n};) wl ! (\tcode = \(*pprocs->name_array_create\)\(&Encoding, str_elts_, countof\(str_elts_\)\);) wl (\tif (code < 0) return code;) wl (}) wl *************** *** 494,507 **** % Finish the procedural initialization code. ! (\tpush(1);) wl ! (\t*op = Font;) wl (\treturn 0;) wl (}) wl - - % Write out the operator initialization table. - (\nop_def ) ws fontproc ws (_op_defs[] = {) wl - (\t{"0.font_) ws FontName wt (", ) ws fontproc ws (},) wl - (\top_def_end(0)) wl - (};) wl end --- 519,525 ---- % Finish the procedural initialization code. ! (\t*pfont = Font;) wl (\treturn 0;) wl (}) wl end *************** *** 512,523 **** % If the program was invoked from the command line, run it now. [ shellarguments ! { counttomark 2 eq ! { exch cvn dup FontDirectory exch known { dup FontDirectory exch undef } if findfont setfont writefont } { cleartomark ! (Usage: font2c fontname cfilename.c\n) print ( e.g.: font2c Courier cour.c\n) print flush mark --- 530,546 ---- % If the program was invoked from the command line, run it now. [ shellarguments ! { counttomark dup 2 eq exch 3 eq or ! { counttomark -1 roll cvn dup FontDirectory exch known { dup FontDirectory exch undef } if findfont setfont + counttomark 1 eq + { % Construct the procedure name from the file name. + currentfont /FontName get makefontprocname + } + if writefont } { cleartomark ! (Usage: font2c fontname cfilename.c [shortname]\n) print ( e.g.: font2c Courier cour.c\n) print flush mark diff -rc2N gs241/fonts.doc gs25/fonts.doc *** gs241/fonts.doc Mon Apr 6 15:40:42 1992 --- gs25/fonts.doc Mon Aug 10 14:44:40 1992 *************** *** 26,52 **** README. ! Ghostscript fonts ! ----------------- The fonts included with Ghostscript come in several parts: ! - Font data in files *.gsf: each file defines one (transformable) ! font specified in outline form. - BuildChar procedures in gs_fonts.ps: these provide the ! algorithms for interpreting the data in the .gsf files. - The Fontmap file: this relates Ghostscript font names to .gsf ! file names. ! Currently, the fonts supplied with Ghostscript are based on various public ! domain bitmap fonts, mostly the ones supplied with the X11 distribution ! from MIT, and on the public domain Hershey fonts. The fonts are ! distributed in the file `ghostscript-N.NNfonts.tar.Z'. The bitmap-derived ! fonts include the usual Helvetica, Times-Roman, and so on; see the file ! `Fontmap' for the complete list, in the usual roman, italic, bold, and ! bold italic styles (for the most part). The Hershey fonts, on the other ! hand, are quite different from traditional ones; the file `hershey.doc' ! describes them in more detail. There is also a single rather heavy home-grown font called Ugly. This --- 26,52 ---- README. ! About Ghostscript fonts ! ======================= The fonts included with Ghostscript come in several parts: ! - Font data in files *.gsf and *.pfa: each file defines one ! (transformable) font specified in outline form. - BuildChar procedures in gs_fonts.ps: these provide the ! algorithms for interpreting the data in the .gsf or .pfa files. - The Fontmap file: this relates Ghostscript font names to .gsf ! or .pfa file names. ! Currently, most of the fonts supplied with Ghostscript are based on ! various public domain bitmap fonts, primarily the ones supplied with the ! X11 distribution from MIT, and on the public domain Hershey fonts. The ! fonts are distributed in the file `ghostscript-N.NNfonts.tar.Z'. The ! bitmap-derived fonts include the usual Helvetica, Times-Roman, and so on; ! see the file `Fontmap' for the complete list, in the usual roman, italic, ! bold, and bold italic styles (for the most part). The Hershey fonts, on ! the other hand, are quite different from traditional ones; the file ! `hershey.doc' describes them in more detail. There is also a single rather heavy home-grown font called Ugly. This *************** *** 75,79 **** /Times-Roman DoFont - Contents of fonts ----------------- --- 75,78 ---- *************** *** 121,125 **** Adding your own fonts ! --------------------- The program bdftops.ps (and invoking shell script bdftops.bat or bdftops) --- 120,124 ---- Adding your own fonts ! ===================== The program bdftops.ps (and invoking shell script bdftops.bat or bdftops) *************** *** 152,178 **** Precompiling fonts ! ------------------ ! You can compile any font into C and link it into the Ghostscript ! executable. This doesn't have any effect on rendering speed, but it ! eliminates the time for loading the font dynamically. The utility for precompiling fonts is called font2c. (Note that font2c is ! actually a PostScript program, so you must have some version of Ghostscript already running to be able to run font2c.) For example, to ! precompile the Times-Roman font, ! font2c Times-Roman timesrmn.c where the first argument is the font name and the second is the name of ! the .c file. (You can use any file name you want, as long as it ends in .c. It doesn't have to be limited to 8 characters, unless your operating ! system requires this.) - Besides running font2c, you must edit the makefile so that the file will - be compiled from C to machine code, and linked into the executable. First, you must add the compiled fonts "feature" to your platform-specific makefile. On MS-DOS systems, you edit turboc.mak, tbcplus.mak, or ! watc.mak; on Unix systems, you edit makefile. (The situation on VMS ! systems that do not use `make' is too complicated to describe here; ! contact Aladdin Enterprises for assistance.) Find the definition of FEATURE_DEVS in the makefile, e.g., FEATURE_DEVS=filter.dev dps.dev --- 151,195 ---- Precompiling fonts ! ================== ! You can compile any Type 1 font into C and link it into the Ghostscript ! executable. (Type 1 fonts include any font whose name ends with .pfa or ! .pfb, and it also includes all the Ghostscript .gsf fonts except for the ! Hershey fonts.) This doesn't have any effect on rendering speed, but it ! eliminates the time for loading the font dynamically, which may make a big ! difference in total rendering time, especially for multi-page documents. ! (Because of RAM and compiler limitations, you should only use compiled ! fonts on MS-DOS systems if you are using a 32-bit compiler such as Watcom ! C/386 or djgpp; you will run out of memory if you use compiled fonts with ! the Borland compiler.) Fonts that have been precompiled and linked in ! this way do not need to appear in the Fontmap, although if they do appear ! there, no harm is done. The utility for precompiling fonts is called font2c. (Note that font2c is ! a PostScript language program, so you must have some version of Ghostscript already running to be able to run font2c.) For example, to ! precompile the Times-Italic font, ! font2c Times-Italic ptmri.c where the first argument is the font name and the second is the name of ! the .c file. You can use any file name you want, as long as it ends in .c. It doesn't have to be limited to 8 characters, unless your operating ! system requires this. We suggest that you use names xxxx.c, where ! xxxx.gsf or xxxx.pfa is the name of the font file in the Fontmap file, ! just so you don't have to keep track of another set of names. (If you are ! running on a VMS platform, or another platform where the C compiler has a ! limit on the length of identifiers, you must do something slightly more ! complicated; see the section 'Platforms with identifier length limits' ! below.) ! ! Besides running font2c, you must arrange things so that the file will be ! compiled from C to machine code, and linked into the executable. All ! environments except VMS use the same procedure for this, which we will now ! describe. For VMS environments, the necessary information is contained in ! comments in the command files (vms-cc.mak and vms-gcc.mak); if you are ! using Ghostscript on VMS, ignore the rest of this subsection. First, you must add the compiled fonts "feature" to your platform-specific makefile. On MS-DOS systems, you edit turboc.mak, tbcplus.mak, or ! watc.mak; on Unix systems, you edit makefile. Find the definition of FEATURE_DEVS in the makefile, e.g., FEATURE_DEVS=filter.dev dps.dev *************** *** 183,219 **** systems, you edit gs.mak; on Unix systems, you edit makefile. Find the line in the relevant makefile that says ! ccfonts_=ugly.$(OBJ) cour.$(OBJ) Edit this to add your compiled font file names, e.g., ! ccfonts_=ugly.$(OBJ) cour.$(OBJ) timesrmn.$(OBJ) Then find the line that says ! $(SHP)gsaddmod ccfonts -oper font_Ugly font_Courier ! Add your own fonts to the end of this line. If the line gets too long, ! add another line of the same form, e.g., ! $(SHP)gsaddmod ccfonts -oper font_Ugly font_Courier ! $(SHP)gsaddmod ccfonts -oper font_Times_Roman ! Notice that you must replace `-' by `_' in the font name. Now find the ! lines that say ugly.$(OBJ): ugly.c $(CCFONT) ! ! cour.$(OBJ): cour.c $(CCFONT) ! Add a similar line for each font, separating these lines from each other ! by a blank line. In our example, ugly.$(OBJ): ugly.c $(CCFONT) ! cour.$(OBJ): cour.c $(CCFONT) - timesrmn.$(OBJ): timesrmn.c $(CCFONT) - Finally, run `make'. The executable will now include the fonts you added. They will be present in FontDirectory when Ghostscript starts up. ! Fonts that have been precompiled and linked in this way do not need to ! appear in the Fontmap, although if they do appear there, no harm is done. ! ! Because of RAM and compiler limitations, you shouldn't use compiled fonts ! on MS-DOS systems unless you are using a 32-bit compiler such as Watcom ! C/386 or djgpp. ! ! Note that ugly.c and cour.c are not supplied with the Ghostscript fileset, ! since they are quite large and can easily be recreated using the font2c ! program as described above. --- 200,262 ---- systems, you edit gs.mak; on Unix systems, you edit makefile. Find the line in the relevant makefile that says ! ccfonts_=ugly.$(OBJ) Edit this to add your compiled font file names, e.g., ! ccfonts_=ugly.$(OBJ) ptmri.$(OBJ) Then find the line that says ! $(SHP)gsaddmod ccfonts -font Ugly ! Add your own fonts to the end of this line, e.g., ! $(SHP)gsaddmod ccfonts -font Ugly Times_Italic ! Notice that you must replace `-' by `_' in the font name. If the line ! gets too long, add another line of the same form, e.g., ! $(SHP)gsaddmod ccfonts -font Ugly ! $(SHP)gsaddmod ccfonts -font Times_Italic ! Now find the lines that say ugly.$(OBJ): ugly.c $(CCFONT) ! $(CC) $(CCFLAGS) -c ugly.c ! Add a similar pair of lines for each font, separating these entries from ! the existing entries and from each other by a blank line. (The makefile ! includes lines for a few more fonts than this already.) In our example, ugly.$(OBJ): ugly.c $(CCFONT) + $(CC) $(CCFLAGS) -c ugly.c ! ptmri.$(OBJ): ptmri.c $(CCFONT) ! $(CC) $(CCFLAGS) -c ptmri.c Finally, run `make'. The executable will now include the fonts you added. They will be present in FontDirectory when Ghostscript starts up. ! Note that ugly.c, ncrr.c, etc. are not supplied with the Ghostscript ! fileset, since they are quite large and can easily be recreated using the ! font2c program as described above. ! ! Platforms with identifier length limits ! --------------------------------------- ! ! On some platforms, the C compiler and/or linker have a limit on the number ! of significant characters in an identifier. On such platforms, you must ! do a little extra work. ! ! Let N be the maximum number of significant characters in an identifier ! (typically 31). For each font whose name is longer than N-5 characters, ! pick an arbitrary identifier that we will call the "short name". This can ! be any string you want, as long as it contains only letters, digits, and ! underscores; is no longer than N-5 characters; and is not the same as any ! other font name or short name. A good choice for this would be to use the ! name of the C file. (There is no harm in doing this for fonts with names ! shorter than N-5 characters, it's just not necessary.) ! ! You must do two different things for fonts that require a short name. ! First, you must supply the short name as a third argument to the font2c ! program. For example, to compile NewCenturySchlbk-BoldItalic using the ! short name "pncbi", ! font2c NewCenturySchlbk-BoldItalic pncbi.c pncbi ! Then when you add the font to the gsaddmod line in the makefile, use the ! short name, not the actual font name, e.g., ! $(SHP)gsaddmod ccfonts -font pncbi ! instead of ! $(SHP)gsaddmod ccfonts -font NewCenturySchlbk_BoldItalic ! Everything else is as described above. ! ! This procedure doesn't change the name of the font in the Fontmap, or as ! seen from within Ghostscript; it's just a workaround for a limitation of ! some older compilers. diff -rc2N gs241/fonts.mak gs25/fonts.mak *** gs241/fonts.mak Wed Apr 8 18:30:04 1992 --- gs25/fonts.mak Thu Jun 18 04:07:24 1992 *************** *** 1,3 **** ! # Copyright (C) 1991 Aladdin Enterprises. All rights reserved. # Distributed by Free Software Foundation, Inc. # --- 1,3 ---- ! # Copyright (C) 1991, 1992 Aladdin Enterprises. All rights reserved. # Distributed by Free Software Foundation, Inc. # *************** *** 22,30 **** AFM=afm ! BDF=bdf FONTS=fonts ! fonts: AvantGarde Bookman Charter Courier Helvetica NewCenturySchlbk \ ! Palatino Symbol TimesRoman Ugly Utopia ZapfChancery ZapfDingbats # ---------------------------------------------------------------- --- 22,32 ---- AFM=afm ! BDF=fonts/bdf FONTS=fonts + PFA=fonts/pfa ! fonts: AvantGarde Bookman CharterBT Courier Cyrillic Helvetica \ ! NewCenturySchlbk Palatino Symbol TimesRoman \ ! Ugly Utopia ZapfChancery ZapfDingbats # ---------------------------------------------------------------- *************** *** 32,41 **** # Each Ghostscript font has a uniqueID (an integer). This is used # to identify distinct fonts within the Ghostscript font machinery. ! # since some P*stScr*pt programs assume that adding a small integer # to a uniqueID produces a new, distinct, unused uniqueID, # the uniqueID values in this file are all multiples of 10. # To avoid some conflicts with Adobe's numbering scheme, the uniqueID ! # values in this file all lie between 4000000 and 4999999. ! # The uniqueID is also used only when converting the font. # The algorithm for computing the UniqueID is given below. --- 34,43 ---- # Each Ghostscript font has a uniqueID (an integer). This is used # to identify distinct fonts within the Ghostscript font machinery. ! # since some PostScript programs assume that adding a small integer # to a uniqueID produces a new, distinct, unused uniqueID, # the uniqueID values in this file are all multiples of 10. # To avoid some conflicts with Adobe's numbering scheme, the uniqueID ! # values in this file for Ghostscript's own fonts all lie between ! # 4000000 and 4999999. (The uniqueID is used only when converting the font.) # The algorithm for computing the UniqueID is given below. *************** *** 76,79 **** --- 78,82 ---- # ---------------------------------------------------------------- # b = Bitstream + # n = IBM # p = Adobe (`p' for PostScript) # *************** *** 85,90 **** # 08 = Avant Garde = pag (Adobe) # 11 = Bookman = pbk (Adobe) ! # 01 = Charter = bch (Bitstream) ! # 02 = Courier = pcr (Adobe) # 03 = Helvetica = phv (Adobe) # 04 = New Century Schoolbook = pnc (Adobe) --- 88,93 ---- # 08 = Avant Garde = pag (Adobe) # 11 = Bookman = pbk (Adobe) ! # 01 = CharterBT = bch (Bitstream) ! # 02 = Courier = ncr (IBM) # 03 = Helvetica = phv (Adobe) # 04 = New Century Schoolbook = pnc (Adobe) *************** *** 93,96 **** --- 96,100 ---- # 06 = Times = ptm (Adobe) # 00 = Ugly = ugly (public domain) + # -- Utopia = put (Adobe) # 07 = Zapf Chancery = zc (public domain) # 10 = Zapf Dingbats = pzd (Adobe) *************** *** 190,211 **** # ---------------- Charter ---------------- - # (No separate metrics for this font.) ! Charter: $(FONTS)/bchr.gsf $(FONTS)/bchri.gsf $(FONTS)/bchb.gsf \ $(FONTS)/bchbi.gsf ! $(FONTS)/bchr.gsf: $(BDF)/charR24.bdf bdftops $(BDF)/charR24.bdf \ $(FONTS)/bchr.gsf Charter-Roman 4010000 ! $(FONTS)/bchri.gsf: $(BDF)/charI24.bdf bdftops $(BDF)/charI24.bdf \ $(FONTS)/bchri.gsf Charter-Italic 4010100 ! $(FONTS)/bchb.gsf: $(BDF)/charB24.bdf bdftops $(BDF)/charB24.bdf \ $(FONTS)/bchb.gsf Charter-Bold 4011000 ! $(FONTS)/bchbi.gsf: $(BDF)/charBI24.bdf bdftops $(BDF)/charBI24.bdf \ $(FONTS)/bchbi.gsf Charter-BoldItalic 4011100 --- 194,220 ---- # ---------------- Charter ---------------- ! # These are the fonts contributed by Bitstream to X11R5. ! ! CharterBT: $(FONTS)/bchr.gsf $(FONTS)/bchri.gsf $(FONTS)/bchb.gsf \ $(FONTS)/bchbi.gsf ! # Old Charter, no longer used. ! $(FONTS)/_bchr.gsf: $(BDF)/charR24.bdf bdftops $(BDF)/charR24.bdf \ $(FONTS)/bchr.gsf Charter-Roman 4010000 ! # Old Charter-Italic, no longer used. ! $(FONTS)/_bchri.gsf: $(BDF)/charI24.bdf bdftops $(BDF)/charI24.bdf \ $(FONTS)/bchri.gsf Charter-Italic 4010100 ! # Old Charter-Bold, no longer used. ! $(FONTS)/_bchb.gsf: $(BDF)/charB24.bdf bdftops $(BDF)/charB24.bdf \ $(FONTS)/bchb.gsf Charter-Bold 4011000 ! # Old Charter-BoldItalic, no longer used. ! $(FONTS)/_bchbi.gsf: $(BDF)/charBI24.bdf bdftops $(BDF)/charBI24.bdf \ $(FONTS)/bchbi.gsf Charter-BoldItalic 4011100 *************** *** 215,232 **** # Ghostscript has two sets of Courier fonts, a lower-quality set derived # from the X11R4 bitmaps, and a higher-quality set contributed by IBM ! # to X11R5 in Type 1 form. Unfortunately, the two sets don't contain ! # the same variants, and some PostScript files use Courier-Oblique rather ! # than Courier-Italic. For this reason, we keep the X11R4 Oblique fonts. ! ! Courier: $(FONTS)/cour.pfa $(FONTS)/couri.pfa $(FONTS)/courb.pfa \ ! $(FONTS)/courbi.pfa $(FONTS)/pcrro.gsf $(FONTS)/pcrbo.gsf ! # $(FONTS)/pcrr.gsf $(FONTS)/pcrb.gsf # Old Courier, longer used. ! $(FONTS)/pcrr.gsf: $(BDF)/courR24.bdf $(AFM)/courier.afm bdftops $(BDF)/courR24.bdf $(AFM)/courier.afm \ $(FONTS)/pcrr.gsf Courier 4020000 ! $(FONTS)/pcrro.gsf: $(BDF)/courO24.bdf $(AFM)/courier_oblique.afm bdftops $(BDF)/courO24.bdf $(AFM)/courier_oblique.afm \ $(FONTS)/pcrro.gsf Courier-Oblique 4020200 --- 224,239 ---- # Ghostscript has two sets of Courier fonts, a lower-quality set derived # from the X11R4 bitmaps, and a higher-quality set contributed by IBM ! # to X11R5 in Type 1 form. The former are no longer used. ! ! Courier: $(FONTS)/ncrr.gsf $(FONTS)/ncri.gsf $(FONTS)/ncrb.gsf \ ! $(FONTS)/ncrbi.gsf # Old Courier, longer used. ! $(FONTS)/_pcrr.gsf: $(BDF)/courR24.bdf $(AFM)/courier.afm bdftops $(BDF)/courR24.bdf $(AFM)/courier.afm \ $(FONTS)/pcrr.gsf Courier 4020000 ! % Old Courier-Oblique, no longer used. ! $(FONTS)/_pcrro.gsf: $(BDF)/courO24.bdf $(AFM)/courier_oblique.afm bdftops $(BDF)/courO24.bdf $(AFM)/courier_oblique.afm \ $(FONTS)/pcrro.gsf Courier-Oblique 4020200 *************** *** 233,244 **** # Old Courier-Bold, no longer used. ! $(FONTS)/pcrb.gsf: $(BDF)/courB24.bdf $(AFM)/courier_bold.afm bdftops $(BDF)/courB24.bdf $(AFM)/courier_bold.afm \ $(FONTS)/pcrb.gsf Courier-Bold 4021000 ! $(FONTS)/pcrbo.gsf: $(BDF)/courBO24.bdf $(AFM)/courier_boldoblique.afm bdftops $(BDF)/courBO24.bdf $(AFM)/courier_boldoblique.afm \ $(FONTS)/pcrbo.gsf Courier-BoldOblique 4021200 # ---------------- Helvetica ---------------- --- 240,258 ---- # Old Courier-Bold, no longer used. ! $(FONTS)/_pcrb.gsf: $(BDF)/courB24.bdf $(AFM)/courier_bold.afm bdftops $(BDF)/courB24.bdf $(AFM)/courier_bold.afm \ $(FONTS)/pcrb.gsf Courier-Bold 4021000 ! % Old Courier-BoldOblique, no longer used. ! $(FONTS)/_pcrbo.gsf: $(BDF)/courBO24.bdf $(AFM)/courier_boldoblique.afm bdftops $(BDF)/courBO24.bdf $(AFM)/courier_boldoblique.afm \ $(FONTS)/pcrbo.gsf Courier-BoldOblique 4021200 + # ---------------- Cyrillic ---------------- + + # These are shareware fonts of questionable quality. + + Cyrillic: $(FONTS)/cyr.gsf $(FONTS)/cyri.gsf + # ---------------- Helvetica ---------------- *************** *** 350,360 **** # (Already in Type 1 form.) ! Utopia: $(FONTS)/utrg.pfa $(FONTS)/uti.pfa $(FONTS)/utb.pfa \ ! $(FONTS)/utbi.pfa # ---------------- Zapf Chancery ---------------- ! ZapfChancery: $(FONTS)/zcr.gsf $(FONTS)/zcri.gsf $(FONTS)/zcro.gsf \ ! $(FONTS)/zcb.gsf $(FONTS)/zcr.gsf: $(BDF)/zcr24.bdf $(AFM)/ZapfChancery-Roman.afm --- 364,373 ---- # (Already in Type 1 form.) ! Utopia: $(FONTS)/putr.gsf $(FONTS)/puti.gsf $(FONTS)/putb.gsf \ ! $(FONTS)/putbi.gsf # ---------------- Zapf Chancery ---------------- ! ZapfChancery: $(FONTS)/zcr.gsf $(FONTS)/zcro.gsf $(FONTS)/zcb.gsf $(FONTS)/zcr.gsf: $(BDF)/zcr24.bdf $(AFM)/ZapfChancery-Roman.afm *************** *** 361,369 **** bdftops $(BDF)/zcr24.bdf $(AFM)/ZapfChancery-Roman.afm \ $(FONTS)/zcr.gsf ZapfChancery 4070000 - - # We fake italic with oblique, but use the italic metrics. - $(FONTS)/zcri.gsf: $(BDF)/zcro24.bdf $(AFM)/ZapfChancery-MediumItalic.afm - bdftops $(BDF)/zcro24.bdf $(AFM)/ZapfChancery-MediumItalic.afm \ - $(FONTS)/zcro.gsf ZapfChancery-MediumItalic 4070100 $(FONTS)/zcro.gsf: $(BDF)/zcro24.bdf $(AFM)/ZapfChancery-MediumItalic.afm --- 374,377 ---- diff -rc2N gs241/gcc-head.mak gs25/gcc-head.mak *** gs241/gcc-head.mak Fri Apr 10 05:46:10 1992 --- gs25/gcc-head.mak Sat Aug 1 03:07:34 1992 *************** *** 27,35 **** # ------ Generic options ------ # # Define the default directory/ies for the runtime # initialization and font files. Separate multiple directories with a :. - # `pwd` means use the directory in which the 'make' is being done. ! GS_LIB_DEFAULT=`pwd`:`pwd`/fonts # Define the name of the Ghostscript initialization file. --- 27,47 ---- # ------ Generic options ------ # + # Define the installation commands and target directories for + # executables and files. Only relevant to `make install'. + + INSTALL = install -c + INSTALL_PROGRAM = $(INSTALL) -m 775 + INSTALL_DATA = $(INSTALL) -m 664 + + prefix = /usr/local + exec_prefix = $(prefix) + bindir = $(exec_prefix)/bin + datadir = $(prefix)/lib + gsdatadir = $(datadir)/ghostscript + # Define the default directory/ies for the runtime # initialization and font files. Separate multiple directories with a :. ! GS_LIB_DEFAULT=$(gsdatadir):$(gsdatadir)/fonts # Define the name of the Ghostscript initialization file. *************** *** 86,89 **** --- 98,103 ---- # This can be null if handled in some other way (e.g., the files are # in /usr/include, or the directory is supplied by an environment variable). + # Note that x_.h expects to find the header files in $(XINCLUDE)/X11, + # not in $(XINCLUDE). XINCLUDE=-I/usr/local/X/include *************** *** 93,107 **** XLIBDIRS=-L/usr/local/X/lib - - # Define the installation commands and target directories for - # executables and files. Only relevant to `make install'. - - INSTALL = install -c - INSTALL_PROGRAM = $(INSTALL) -m 775 - INSTALL_DATA = $(INSTALL) -m 664 - - prefix = /usr/local - bindir = $(prefix)/bin - libdir = $(prefix)/lib/ghostscript # ------ Devices and features ------ # --- 107,110 ---- diff -rc2N gs241/gconfig.c gs25/gconfig.c *** gs241/gconfig.c Tue Apr 21 05:17:20 1992 --- gs25/gconfig.c Mon Jun 1 02:38:10 1992 *************** *** 33,37 **** #define ref_(t) struct { struct tas_s tas; t value; } #define string_v(n,s)\ ! { {(t_string<='a' && c<='z' ? gs_debug[c] | gs_debug[c^32] : gs_debug[c]) + # define if_debug0(c,s)\ + if (debug_c(c)) dprintf(s) + # define if_debug1(c,s,a1)\ + if (debug_c(c)) dprintf1(s,a1) + # define if_debug2(c,s,a1,a2)\ + if (debug_c(c)) dprintf2(s,a1,a2) + # define if_debug3(c,s,a1,a2,a3)\ + if (debug_c(c)) dprintf3(s,a1,a2,a3) + # define if_debug4(c,s,a1,a2,a3,a4)\ + if (debug_c(c)) dprintf4(s,a1,a2,a3,a4) + # define if_debug5(c,s,a1,a2,a3,a4,a5)\ + if (debug_c(c)) dprintf5(s,a1,a2,a3,a4,a5) + # define if_debug6(c,s,a1,a2,a3,a4,a5,a6)\ + if (debug_c(c)) dprintf6(s,a1,a2,a3,a4,a5,a6) + # define if_debug7(c,s,a1,a2,a3,a4,a5,a6,a7)\ + if (debug_c(c)) dprintf7(s,a1,a2,a3,a4,a5,a6,a7) + # define if_debug8(c,s,a1,a2,a3,a4,a5,a6,a7,a8)\ + if (debug_c(c)) dprintf8(s,a1,a2,a3,a4,a5,a6,a7,a8) + # define if_debug9(c,s,a1,a2,a3,a4,a5,a6,a7,a8,a9)\ + if (debug_c(c)) dprintf9(s,a1,a2,a3,a4,a5,a6,a7,a8,a9) + #else + # define if_debug0(c,s) 0 + # define if_debug1(c,s,a1) 0 + # define if_debug2(c,s,a1,a2) 0 + # define if_debug3(c,s,a1,a2,a3) 0 + # define if_debug4(c,s,a1,a2,a3,a4) 0 + # define if_debug5(c,s,a1,a2,a3,a4,a5) 0 + # define if_debug6(c,s,a1,a2,a3,a4,a5,a6) 0 + # define if_debug7(c,s,a1,a2,a3,a4,a5,a6,a7) 0 + # define if_debug8(c,s,a1,a2,a3,a4,a5,a6,a7,a8) 0 + # define if_debug9(c,s,a1,a2,a3,a4,a5,a6,a7,a8,a9) 0 + #endif diff -rc2N gs241/gdevbgi.c gs25/gdevbgi.c *** gs241/gdevbgi.c Sun Feb 16 18:21:28 1992 --- gs25/gdevbgi.c Sat Aug 15 04:59:48 1992 *************** *** 84,88 **** "bgi", 0, 0, /* width and height are set in bgi_open */ ! 0, 0, /* density is set in bgi_open */ no_margins, dci_black_and_white, --- 84,88 ---- "bgi", 0, 0, /* width and height are set in bgi_open */ ! 1, 1, /* density is set in bgi_open */ no_margins, dci_black_and_white, *************** *** 183,192 **** /* the display screen to an 8.5" x 11" coordinate space. */ /* This may or may not be what is desired! */ ! dev->width = getmaxx() + 1; ! dev->height = getmaxy() + 1; ! dev->y_pixels_per_inch = dev->height / 11.0; { /* Get the aspect ratio from the driver. */ int arx, ary; getaspectratio(&arx, &ary); dev->x_pixels_per_inch = dev->y_pixels_per_inch * ((float)ary / arx); --- 183,195 ---- /* the display screen to an 8.5" x 11" coordinate space. */ /* This may or may not be what is desired! */ ! if ( dev->width == 0 ) ! dev->width = getmaxx() + 1; ! if ( dev->height == 0 ) ! dev->height = getmaxy() + 1; ! if ( dev->y_pixels_per_inch == 1 ) { /* Get the aspect ratio from the driver. */ int arx, ary; getaspectratio(&arx, &ary); + dev->y_pixels_per_inch = dev->height / 11.0; dev->x_pixels_per_inch = dev->y_pixels_per_inch * ((float)ary / arx); *************** *** 242,249 **** int bgi_copy_mono(gx_device *dev, ! byte *base, int sourcex, int raster, gx_bitmap_id id, int x, int y, int w, int h, gx_color_index zero, gx_color_index one) ! { byte *ptr_line = base + (sourcex >> 3); int left_bit = 0x80 >> (sourcex & 7); int dest_y = y, end_x = x + w; --- 245,252 ---- int bgi_copy_mono(gx_device *dev, ! const byte *base, int sourcex, int raster, gx_bitmap_id id, int x, int y, int w, int h, gx_color_index zero, gx_color_index one) ! { const byte *ptr_line = base + (sourcex >> 3); int left_bit = 0x80 >> (sourcex & 7); int dest_y = y, end_x = x + w; *************** *** 269,273 **** while ( h-- ) /* for each line */ ! { byte *ptr_source = ptr_line; register int dest_x = x; register int bit = left_bit; --- 272,276 ---- while ( h-- ) /* for each line */ ! { const byte *ptr_source = ptr_line; register int dest_x = x; register int bit = left_bit; *************** *** 290,298 **** int bgi_copy_color(gx_device *dev, ! byte *base, int sourcex, int raster, gx_bitmap_id id, int x, int y, int w, int h) { if ( gx_device_has_color(dev) ) { /* color device, four bits per pixel */ ! byte *line = base + (sourcex >> 1); int dest_y = y, end_x = x + w; --- 293,301 ---- int bgi_copy_color(gx_device *dev, ! const byte *base, int sourcex, int raster, gx_bitmap_id id, int x, int y, int w, int h) { if ( gx_device_has_color(dev) ) { /* color device, four bits per pixel */ ! const byte *line = base + (sourcex >> 1); int dest_y = y, end_x = x + w; *************** *** 299,303 **** if ( w <= 0 ) return 0; while ( h-- ) /* for each line */ ! { byte *source = line; register int dest_x = x; if ( sourcex & 1 ) /* odd nibble first */ --- 302,306 ---- if ( w <= 0 ) return 0; while ( h-- ) /* for each line */ ! { const byte *source = line; register int dest_x = x; if ( sourcex & 1 ) /* odd nibble first */ *************** *** 345,349 **** /* Note that this also does the right thing for colored tiles. */ int ! bgi_tile_rectangle(gx_device *dev, gx_bitmap *tile, int x, int y, int w, int h, gx_color_index czero, gx_color_index cone, int px, int py) --- 348,352 ---- /* Note that this also does the right thing for colored tiles. */ int ! bgi_tile_rectangle(gx_device *dev, const gx_bitmap *tile, int x, int y, int w, int h, gx_color_index czero, gx_color_index cone, int px, int py) diff -rc2N gs241/gdevbit.c gs25/gdevbit.c *** gs241/gdevbit.c Wed Nov 27 02:08:34 1991 --- gs25/gdevbit.c Tue Aug 11 05:00:20 1992 *************** *** 23,30 **** /* Define the device parameters. */ ! #define X_DPI 400 ! #define Y_DPI 400 ! #define WIDTH_10THS 80 /* 440 */ ! #define HEIGHT_10THS 80 /* 1080 */ /* The device descriptor */ --- 23,30 ---- /* Define the device parameters. */ ! #define X_DPI 72 ! #define Y_DPI 72 ! #define WIDTH_10THS 85 ! #define HEIGHT_10THS 110 /* The device descriptor */ *************** *** 41,52 **** bit_print_page(gx_device_printer *pdev, FILE *prn_stream) { /* Just dump the bits on the file. */ int line_size = gdev_mem_bytes_per_scan_line((gx_device *)pdev); int lnum; byte *in = (byte *)gs_malloc(line_size, 1, "bit_print_page(in)"); ! if ( in == 0 ) return -1; for ( lnum = 0; lnum < pdev->height; lnum++ ) { gdev_prn_copy_scan_lines(pdev, lnum, in, line_size); ! /****** fwrite(in, 1, line_size, prn_stream); ! ******/ } gs_free(in, line_size, 1, "bit_print_page(in)"); --- 41,55 ---- bit_print_page(gx_device_printer *pdev, FILE *prn_stream) { /* Just dump the bits on the file. */ + /* If the file is 'nul', don't even do the writes. */ int line_size = gdev_mem_bytes_per_scan_line((gx_device *)pdev); int lnum; byte *in = (byte *)gs_malloc(line_size, 1, "bit_print_page(in)"); ! int nul = !strcmp(pdev->fname, "nul"); ! if ( in == 0 ) ! return_error(gs_error_VMerror); for ( lnum = 0; lnum < pdev->height; lnum++ ) { gdev_prn_copy_scan_lines(pdev, lnum, in, line_size); ! if ( !nul ) ! fwrite(in, 1, line_size, prn_stream); } gs_free(in, line_size, 1, "bit_print_page(in)"); diff -rc2N gs241/gdevbj10.c gs25/gdevbj10.c *** gs241/gdevbj10.c Sat Apr 18 04:55:54 1992 --- gs25/gdevbj10.c Tue Jul 21 05:35:12 1992 *************** *** 53,57 **** byte *in = (byte *)gs_malloc(8, line_size, "bj10e_print_page(in)"); byte *out = (byte *)gs_malloc(bits_per_column, line_size, "bj10e_print_page(out)"); ! static char cmp[18] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; int lnum = 0; int skip = 0; --- 53,57 ---- byte *in = (byte *)gs_malloc(8, line_size, "bj10e_print_page(in)"); byte *out = (byte *)gs_malloc(bits_per_column, line_size, "bj10e_print_page(out)"); ! static const char cmp[18] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; int lnum = 0; int skip = 0; *************** *** 59,63 **** if ( in == 0 || out == 0 ) ! return -1; /* Initialize the printer. */ --- 59,66 ---- if ( in == 0 || out == 0 ) ! { code = gs_error_VMerror; ! gs_note_error(code); ! goto out; ! } /* Initialize the printer. */ *************** *** 83,89 **** /* the following code, but all systems seem to implement */ /* them so badly that this code is faster. */ ! { register long *zip = (long *)in; register int zcnt = line_size; ! static long zeroes[4] = { 0, 0, 0, 0 }; for ( ; zcnt >= 4 * sizeof(long); zip += 4, zcnt -= 4 * sizeof(long) ) { if ( zip[0] | zip[1] | zip[2] | zip[3] ) --- 86,92 ---- /* the following code, but all systems seem to implement */ /* them so badly that this code is faster. */ ! { register const long *zip = (const long *)in; register int zcnt = line_size; ! static const long zeroes[4] = { 0, 0, 0, 0 }; for ( ; zcnt >= 4 * sizeof(long); zip += 4, zcnt -= 4 * sizeof(long) ) { if ( zip[0] | zip[1] | zip[2] | zip[3] ) *************** *** 90,94 **** goto notz; } ! if ( !memcmp(in, (char *)zeroes, zcnt) ) { /* Line is all zero, skip */ lnum++; --- 93,97 ---- goto notz; } ! if ( !memcmp(in, (const char *)zeroes, zcnt) ) { /* Line is all zero, skip */ lnum++; *************** *** 161,166 **** xit: fputc(014, prn_stream); /* form feed */ fflush(prn_stream); ! gs_free((char *)out, bits_per_column, line_size, "bj10e_print_page(out)"); ! gs_free((char *)in, 8, line_size, "bj10e_print_page(in)"); return code; } --- 164,172 ---- xit: fputc(014, prn_stream); /* form feed */ fflush(prn_stream); ! out: if ( out != 0 ) ! gs_free((char *)out, bits_per_column, line_size, ! "bj10e_print_page(out)"); ! if ( in != 0 ) ! gs_free((char *)in, 8, line_size, "bj10e_print_page(in)"); return code; } diff -rc2N gs241/gdevcdj.c gs25/gdevcdj.c *** gs241/gdevcdj.c Wed Mar 25 10:47:28 1992 --- gs25/gdevcdj.c Wed Aug 19 00:55:32 1992 *************** *** 1,24 **** ! /* ! * Copyright (C) 1991, 1992 Aladdin Enterprises. All rights reserved. ! * Distributed by Free Software Foundation, Inc. ! * ! * This file is part of Ghostscript. ! * ! * Ghostscript is distributed in the hope that it will be useful, but WITHOUT ! * ANY WARRANTY. No author or distributor accepts responsibility to anyone ! * for the consequences of using it or for whether it serves any particular ! * purpose or works at all, unless he says so in writing. Refer to the ! * Ghostscript General Public License for full details. ! * ! * Everyone is granted permission to copy, modify and redistribute Ghostscript, ! * but only under the conditions described in the Ghostscript General Public ! * License. A copy of this license is supposed to have been given to you ! * along with Ghostscript so you can know your rights and responsibilities. ! * It should be in a file named COPYING. Among other things, the copyright ! * notice and this notice must be preserved on all copies. ! */ /* gdevcdj.c */ /* H-P DeskJet 500C driver (colour) for Ghostscript */ #include "gdevprn.h" #include "gdevpcl.h" --- 1,24 ---- ! /* Copyright (C) 1991, 1992 Aladdin Enterprises. All rights reserved. ! Distributed by Free Software Foundation, Inc. ! ! This file is part of Ghostscript. + Ghostscript is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY. No author or distributor accepts responsibility + to anyone for the consequences of using it or for whether it serves any + particular purpose or works at all, unless he says so in writing. Refer + to the Ghostscript General Public License for full details. + + Everyone is granted permission to copy, modify and redistribute + Ghostscript, but only under the conditions described in the Ghostscript + General Public License. A copy of this license is supposed to have been + given to you along with Ghostscript so you can know your rights and + responsibilities. It should be in a file named COPYING. Among other + things, the copyright notice and this notice must be preserved on all + copies. */ + /* gdevcdj.c */ /* H-P DeskJet 500C driver (colour) for Ghostscript */ + #include /* for rand() */ #include "gdevprn.h" #include "gdevpcl.h" *************** *** 26,49 **** /*** *** Note: this driver was contributed by a user, George Cameron: ! *** please contact g.cameron@aberdeen.ac.uk if you have questions. ***/ /* ! * Definitions affecting print quality/speed */ ! /* #define A4 * .. if in Europe */ ! #ifndef SHINGLING /* Interlaced, multi-pass printing */ ! #define SHINGLING 1 /* 0 = none, 1 = 50%, 2 = 25%, 2 is best & slowest */ #endif ! #ifndef DEPLETION /* 'Intelligent' dot-removal */ ! #define DEPLETION 1 /* 0 = none, 1 = 25%, 2 = 50%, 1 best for graphics? */ ! #endif /* Use 0 for transparencies */ /* ! * You may select a resolution of 75, 100, 150, or 300 DPI. ! * Normally you would do this in the makefile or on the gs command line, ! * not here. */ --- 26,63 ---- /*** *** Note: this driver was contributed by a user, George Cameron: ! *** please contact g.cameron@biomed.abdn.ac.uk if you have questions. ***/ /* ! * Note that there are three drivers contained in this code: ! * ! * 1 - cdeskjet: A slightly updated version of the original ! * cdeskjet driver. ! * 2 - cdjcolor: This is the significant addition - a 24-bit ! * Floyd-Steinberg dithering driver, which gives ! * excellent quality, but necessarily results in ! * slow printing. ! * 3 - cdjmono: Included purely to give dj500c owners the benefit ! * of Mode 9 fast printing with their black cartridge. */ ! /* Definitions affecting print quality/speed */ ! ! #ifndef SHINGLING /* Interlaced, multi-pass printing */ ! #define SHINGLING 1 /* 0 = none, 1 = 50%, 2 = 25%, 2 is best & ! * slowest */ #endif ! #ifndef DEPLETION /* 'Intelligent' dot-removal */ ! #define DEPLETION 1 /* 0 = none, 1 = 25%, 2 = 50%, 1 best for ! * graphics? */ ! #endif /* Use 0 for transparencies */ /* ! * You may select a resolution of 75, 100, 150, or 300 DPI. Normally you ! * would do this in the makefile or on the gs command line, not here. ! * ! * If the preprocessor symbol A4 is defined, the default paper size is the ! * European A4 size; otherwise it is the U.S. letter size (8.5"x11"). */ *************** *** 58,238 **** #endif ! /* We round up LINE_SIZE to a multiple of 8 bytes */ ! /* because that's the unit of transposition from pixels to planes. */ ! #define LINE_SIZE ((X_DPI_MAX * 85 / 10 + 63) / 64 * 8) ! ! /* For all DeskJet Printers: * ! * Maximum printing width = 2400 dots = 8" ! * Maximum printing height (colour) = 3100 dots = 10.3" ! * (monochrome) = 3150 dots = 10.5" ! * All Deskjets have 1/2" unprintable bottom margin */ #ifndef A4 ! #define PAPER_SIZE 2 /* US Letter is default size */ ! #define WIDTH_10THS 85 ! #define HEIGHT_10THS 110 ! #define L_MARGIN 0.25 ! #define B_MARGIN 0.5 ! #define R_MARGIN 0.25 ! #define T_MARGIN 0.2 #else ! #define PAPER_SIZE 26 /* A4 size normal in Europe */ ! #define WIDTH_10THS 83 /* 210mm */ ! #define HEIGHT_10THS 117 /* 297mm */ ! #define L_MARGIN 0.134 ! #define B_MARGIN 0.7 ! #define R_MARGIN 0.134 ! #define T_MARGIN 0.66 #endif ! /* The device descriptor */ ! private dev_proc_print_page(cdeskjet_print_page); private gx_device_procs cdeskjet_procs = ! prn_color_procs(gdev_prn_open, gdev_prn_output_page, gdev_prn_close, ! gdev_pcl_3bit_map_rgb_color, gdev_pcl_3bit_map_color_rgb); ! gx_device_printer gs_cdeskjet_device = ! prn_device(cdeskjet_procs, "cdeskjet", ! WIDTH_10THS, HEIGHT_10THS, ! X_DPI, Y_DPI, ! L_MARGIN, R_MARGIN, T_MARGIN, B_MARGIN, ! 3, cdeskjet_print_page); /* Forward references */ private int gdev_pcl_mode9compress(P4(int, const byte *, byte *, byte *)); /* ------ Internal routines ------ */ ! /* Send the page to the printer. Compress each scan line. */ private int ! cdeskjet_print_page(gx_device_printer *pdev, FILE *prn_stream) { ! #define DATA_SIZE (LINE_SIZE * 8) ! byte data[DATA_SIZE]; ! byte plane_data[3][LINE_SIZE], prev_plane_data[3][LINE_SIZE]; ! int x_dpi = pdev->x_pixels_per_inch; ! ! /* Initialize printer. */ ! fputs("\033E", prn_stream); /* reset printer */ ! ! /* ends raster graphics to set raster graphics resolution */ ! fputs("\033*rbC", prn_stream); ! ! /* set raster graphics resolution -- 75, 100, 150 or300 dpi */ ! fprintf(prn_stream, "\033*t%dR", x_dpi); ! ! /* set the line width */ ! fprintf(prn_stream, "\033*r%dS", DATA_SIZE); ! /* paper size, orientation, perf skip, feed from tray*/ ! fprintf(prn_stream, "\033&l%da0o0l1H", PAPER_SIZE); ! /* set the number of color planes */ ! fprintf(prn_stream, "\033*r-%dU", 3); /* always 3, -ve for CMY */ ! /* set depletion level */ ! fprintf(prn_stream, "\033*o%dD", DEPLETION); ! /* set shingling level */ ! fprintf(prn_stream, "\033*o%dQ", SHINGLING); ! /* move to top left of page */ ! fputs("\033&a0H\033&a0V", prn_stream); ! /* select data compression */ ! fputs("\033*b9M", prn_stream); /* mode 9 */ ! /* start raster graphics */ ! fputs("\033*r1A", prn_stream); ! bzero(&prev_plane_data[0][0], LINE_SIZE * 3); ! /* Send each scan line in turn */ ! { ! int lnum; ! int line_size = gdev_prn_bytes_per_scan_line(pdev); ! int line_count = line_size / pdev->color_info.depth; ! int num_blank_lines = 0; ! ! for (lnum = 0; lnum < pdev->height; lnum++) { ! byte _ss *end_data = data + line_size; ! gdev_prn_copy_scan_lines(pdev, lnum, ! (byte *) data, line_size); ! /* Remove trailing 0s. */ ! while (end_data > data && end_data[-1] == 0) ! end_data--; ! if (end_data == data) { /* Blank line */ ! num_blank_lines++; ! } else { ! int i; ! byte _ss *odp; ! ! /* Pad with 0s to fill out the last */ ! /* block of 8 bytes. */ ! memset(end_data, 0, 7); ! ! /* Transpose the data to get pixel planes. */ ! for (i = 0, odp = &plane_data[0][0]; i < DATA_SIZE; ! i += 8, odp++ ! ) { /* The following is for 16-bit machines */ ! #define spread3(c)\ ! { 0, c, c*0x100, c*0x101, c*0x10000L, c*0x10001L, c*0x10100L, c*0x10101L } ! static ulong spr40[8] = spread3(0x40); ! static ulong spr8[8] = spread3(8); ! static ulong spr2[8] = spread3(2); ! register byte _ss *dp = data + i; ! register ulong pword = ! (spr40[dp[0]] << 1) + ! (spr40[dp[1]]) + ! (spr40[dp[2]] >> 1) + ! (spr8[dp[3]] << 1) + ! (spr8[dp[4]]) + ! (spr8[dp[5]] >> 1) + ! (spr2[dp[6]]) + ! (spr2[dp[7]] >> 1); ! odp[0] = (byte) (pword >> 16); ! odp[LINE_SIZE] = (byte) (pword >> 8); ! odp[LINE_SIZE * 2] = (byte) (pword); ! } ! /* Skip blank lines if any */ ! if (num_blank_lines > 0) { /* move down from current ! * position */ ! fprintf(prn_stream, "\033&a+%dV", ! num_blank_lines * (720 / Y_DPI)); ! num_blank_lines = 0; ! bzero(&prev_plane_data[0][0], LINE_SIZE * 3); ! } ! /* Transfer raster graphics */ ! /* in the order C, M, Y. */ ! for (i = 0; i < 3; i++) { ! ! byte temp[LINE_SIZE * 2]; ! ! int count = gdev_pcl_mode9compress(line_count, ! plane_data[2 - i], ! prev_plane_data[2 - i], ! temp); ! ! fprintf(prn_stream, "\033*b%d%c", count, "VVW"[i]); ! fwrite(temp, sizeof(byte), count, prn_stream); ! } } } ! } ! /* end raster graphics */ ! fputs("\033*rbC", prn_stream); ! /* reset to monochrome */ ! fputs("\033*r1U", prn_stream); ! /* eject page */ ! fputs("\033&l0H", prn_stream); ! return 0; } private int ! gdev_pcl_mode9compress(int bytecount, const byte *current, byte *previous, byte *compressed) { register const byte *cur = current; --- 72,479 ---- #endif ! /* ! * Maximum printing width = 2400 dots = 8" * ! * All Deskjets have 1/2" unprintable bottom margin */ + + #define PRINT_LIMIT 0.0625 /* 'real' top margin? */ + + /* Margins are left, bottom, right, top. */ + #define DESKJET_MARGINS_LETTER 0.25, 0.40, 0.25, 0.40 + #define DESKJET_MARGINS_A4 0.134, 0.40, 0.134, 0.25 + #ifndef A4 ! # define WIDTH_10THS 85 ! # define HEIGHT_10THS 110 ! # define DESKJET_MARGINS DESKJET_MARGINS_LETTER #else ! # define WIDTH_10THS 83 /* 210mm */ ! # define HEIGHT_10THS 117 /* 297mm */ ! # define DESKJET_MARGINS DESKJET_MARGINS_A4 #endif ! /* The number of blank lines that make it worthwhile to reposition */ ! /* the cursor. */ ! #define MIN_SKIP_LINES 7 ! ! #define W sizeof(word) ! #define I sizeof(int) ! ! /* Printer types */ ! #define DJ500C_COLOUR 0 /* Standard colour, GS internal dithering */ ! #define DJ500C_COLOUR_FS 1 /* High quality dithering, but can be slow */ ! #define DJ500C_MONO 2 /* Black ink + mode 9 compression */ ! ! /* Procedures */ ! private dev_proc_map_rgb_color (gdev_pcl_true_map_rgb_color); ! private dev_proc_map_color_rgb (gdev_pcl_true_map_color_rgb); ! ! /* The device descriptors */ ! private dev_proc_open_device(hp_dj500c_open); ! private dev_proc_print_page(cdeskjet_print_page); ! private dev_proc_print_page(cdjcolor_print_page); ! private dev_proc_print_page(cdjmono_print_page); ! ! #define hp_dj500c_procs(proc_map_rgb_color, proc_map_color_rgb)\ ! prn_color_matrix_procs(hp_dj500c_open, gdev_pcl_get_initial_matrix,\ ! gdev_prn_output_page, gdev_prn_close,\ ! proc_map_rgb_color, proc_map_color_rgb) ! private gx_device_procs cdeskjet_procs = ! hp_dj500c_procs(gdev_pcl_3bit_map_rgb_color, gdev_pcl_3bit_map_color_rgb); ! ! private gx_device_procs cdjcolor_procs = ! hp_dj500c_procs(gdev_pcl_true_map_rgb_color, gdev_pcl_true_map_color_rgb); ! ! private gx_device_procs cdjmono_procs = ! hp_dj500c_procs(gdev_prn_map_rgb_color, gdev_prn_map_color_rgb); + gx_device_printer gs_cdeskjet_device = + prn_device(cdeskjet_procs, "cdeskjet", + WIDTH_10THS, HEIGHT_10THS, + X_DPI, Y_DPI, + 0, 0, 0, 0, + 3, cdeskjet_print_page); + + gx_device_printer gs_cdjcolor_device = + prn_device(cdjcolor_procs, "cdjcolor", + WIDTH_10THS, HEIGHT_10THS, + X_DPI, Y_DPI, + 0, 0, 0, 0, + 24, cdjcolor_print_page); + + gx_device_printer gs_cdjmono_device = + prn_device(cdjmono_procs, "cdjmono", + WIDTH_10THS, HEIGHT_10THS, + X_DPI, Y_DPI, + 0, 0, 0, 0, + 1, cdjmono_print_page); + /* Forward references */ private int gdev_pcl_mode9compress(P4(int, const byte *, byte *, byte *)); + private int hp_dj500c_print_page(P3(gx_device_printer *, FILE *, int)); + + /* Open the printer and set up the margins. */ + private int + hp_dj500c_open(gx_device *pdev) + { /* Change the margins if necessary. */ + static const float m_a4[4] = { DESKJET_MARGINS_A4 }; + static const float m_letter[4] = { DESKJET_MARGINS_LETTER }; + const float _ds *m = + (gdev_pcl_paper_size(pdev) == PAPER_SIZE_A4 ? m_a4 : + m_letter); + pdev->l_margin = m[0]; + pdev->b_margin = m[1]; + pdev->r_margin = m[2]; + pdev->t_margin = m[3]; + return gdev_prn_open(pdev); + } /* ------ Internal routines ------ */ ! /* The DeskJet500C can compress (mode 9, for all versions) */ private int ! cdeskjet_print_page(gx_device_printer * pdev, FILE * prn_stream) { ! return hp_dj500c_print_page(pdev, prn_stream, DJ500C_COLOUR); ! } ! private int ! cdjcolor_print_page(gx_device_printer * pdev, FILE * prn_stream) ! { ! return hp_dj500c_print_page(pdev, prn_stream, DJ500C_COLOUR_FS); ! } ! private int ! cdjmono_print_page(gx_device_printer * pdev, FILE * prn_stream) ! { ! return hp_dj500c_print_page(pdev, prn_stream, DJ500C_MONO); ! } ! /* Some convenient shorthand .. */ ! #define x_dpi (pdev->x_pixels_per_inch) ! #define y_dpi (pdev->y_pixels_per_inch) ! #define height (pdev->height) ! #define t_margin (pdev->t_margin) ! #define b_margin (pdev->b_margin) ! #define XTRA 12 /* 2 x 6 XTRA values for end-of-line */ ! #define W_XTRA (XTRA * I / W) /* in FSdither error buffers */ ! ! /* Floyd-Steinberg dithering. Often results in a dramatic improvement in ! * subjective image quality, but can also produce dramatic increases in ! * amount of printer data generated and actual printing time!! Mode 9 2D ! * compression is still useful for fairly flat colour or blank areas but its ! * compression is much less effective in areas where the dithering has ! * effectively randomised the dot distribution. This is a first attempt, but ! * it seems to work reasonably well for the images I've tried. */ ! #define MAXVALUE 0xff ! #define THRESHOLD 0x80 ! #define C 4 /* ought to be 8, but this seems to be too much */ ! #define FSdither(inP, out, errP, Err, Bit, DD, II, Offset)\ ! oldErr = Err;\ ! Err = (* DD errP + ((Err * 7 + C) >> 4) + *(DD inP II));\ ! if (Err > THRESHOLD) {\ ! out |= Bit;\ ! Err -= MAXVALUE;\ ! }\ ! errP[Offset 6] += ((oldErr * 3 + C) >> 4);\ ! errP[Offset 3] += ((oldErr * 5 + C) >> 4);\ ! * errP II = ((oldErr + C) >> 4); ! /* Send the page to the printer. Compress each scan line. */ ! private int ! hp_dj500c_print_page(gx_device_printer * pdev, FILE * prn_stream, int ptype) ! { ! /* We round up buffer space to a multiple of 24 bytes because that's the ! * unit of transposition from pixels to planes in 24-bit mode; it's hardly ! * worth trying to save a few bytes by being less generous in other modes. */ ! int line_size = gdev_prn_bytes_per_scan_line(pdev); ! int line_size_words = (line_size + W - 1) / W; ! int plane_size = (line_size + 23) / 24; ! int buffer_size = plane_size * 24; ! int paper_size = gdev_pcl_paper_size((gx_device *)pdev); ! int num_comps = pdev->color_info.num_components; ! int depletion = DEPLETION; ! int shingling = SHINGLING; ! int *errors; ! byte *data, *plane_data[3], *prev_plane_data[3], *out_data; ! word *storage, *data_words; ! uint storage_size_words; ! ! switch (ptype) { ! case DJ500C_COLOUR: ! plane_size *= 3; /* should really have divided by 8, not 24 */ ! storage_size_words = plane_size / W * (8 + 3 + 3 + 2); ! /* data, plane, prev_plane, out_data */ ! break; ! case DJ500C_COLOUR_FS: ! storage_size_words = plane_size / W * (24 * I + 24 + 3 + 3 + 2) + W_XTRA; ! /* errors, data, plane, prev_plane, out_data, XTRA */ ! shingling = 2; /* this is a maximum-quality mode */ ! break; ! case DJ500C_MONO: ! plane_size *= 24; /* (ie. same as buffer size) */ ! storage_size_words = plane_size / W * (1 + 1 + 2); ! /* plane, prev_plane, out_data */ ! break; ! } ! storage = (ulong *) gs_malloc(storage_size_words, W, "hp_dj500c_print_page"); ! data_words = storage; ! ! if (storage == 0) /* can't allocate working area */ ! return_error(gs_error_VMerror); ! else { ! int i; ! byte *p = data = (byte *) storage; ! if ((ptype == DJ500C_COLOUR) || (ptype == DJ500C_COLOUR_FS)) { ! p += buffer_size; ! } ! if (ptype == DJ500C_COLOUR_FS) { ! errors = (int *)p; ! p += (buffer_size + XTRA) * I; ! } ! for (i = 0; i < num_comps; i++) { ! plane_data[i] = p; ! p += plane_size; ! } ! for (i = 0; i < num_comps; i++) { ! prev_plane_data[i] = p; ! p += plane_size; ! } ! out_data = p; /* size is plane_size x 2 */ ! } ! /* Clear temp storage */ ! memset(storage, 0, storage_size_words * W); ! /* Initialize printer. */ ! fputs("\033E", prn_stream); /* reset printer */ ! fputs("\033*rbC", prn_stream); /* end raster graphics */ ! fprintf(prn_stream, "\033*t%dR", (int)x_dpi); /* set resolution */ ! fprintf(prn_stream, "\033&l%da0o0e0L", paper_size); /* paper size etc. */ ! ! /* set the number of color planes (1 or 3). -3 means CMY in colour mode */ ! fprintf(prn_stream, "\033*r-%dU", num_comps); ! ! /* set depletion and shingling levels */ ! fprintf(prn_stream, "\033*o%dd%dQ", depletion, shingling); ! ! /* move to top left of printed area */ ! #define OFFSET (t_margin - PRINT_LIMIT) /* Offset to print position */ ! fprintf(prn_stream, "\033*p0x%dY", (int)(Y_DPI_MAX * OFFSET)); ! ! /* select data compression */ ! fputs("\033*b9M", prn_stream);/* mode 9 */ ! ! /* Start raster graphics. From now on */ ! /* all escape commands start with \033*b, */ ! /* so we combine them. */ ! fputs("\033*r1A\033*b", prn_stream); ! ! /* Send each scan line in turn */ ! { ! int lnum, i; ! int lend = height - (t_margin + b_margin) * y_dpi; ! int num_blank_lines = 0; ! word rmask = ~(word) 0 << (-pdev->width & (W * 8 - 1)); ! int c, m, y, cErr, mErr, yErr; ! int going_up = 1; ! byte *cP = plane_data[0], *mP = plane_data[1], *yP = plane_data[2]; ! register int *ep = errors + (XTRA / 2); ! register byte *dp = data; ! ! c = m = y = cErr = mErr = yErr = 0; ! ! if (ptype == DJ500C_COLOUR_FS) { /* Randomly seed initial error buffer */ ! for (i = 0; i < buffer_size; i++) { ! *ep++ = (rand() % MAXVALUE) >> 4; ! } ! ep = errors + (XTRA / 2); ! } ! for (lnum = 0; lnum < lend; lnum++) { ! register word *end_data = data_words + line_size_words; ! gdev_prn_copy_scan_lines(pdev, lnum, data, line_size); ! ! /* Mask off 1-bits beyond the line width. */ ! end_data[-1] &= rmask; ! ! /* Remove trailing 0s. */ ! while (end_data > data_words && end_data[-1] == 0) ! end_data--; ! if (end_data == data_words) { /* Blank line */ ! num_blank_lines++; ! continue; ! } ! /* Skip blank lines if any */ ! if (num_blank_lines > 0) { ! if (num_blank_lines < MIN_SKIP_LINES) { ! /* Moving down from current position */ ! /* causes head motion on the DeskJet, so */ ! /* if the number of lines is small, */ ! /* we're better off printing blanks. */ ! fputs("y", prn_stream); /* Clear current and seed rows */ ! for (; num_blank_lines; num_blank_lines--) ! fputs("w", prn_stream); ! } else { ! fprintf(prn_stream, "%dy", num_blank_lines); ! } ! memset(prev_plane_data[0], 0, plane_size * num_comps); ! num_blank_lines = 0; ! } { /* Printing non-blank lines */ ! int i, j; ! byte *odp; ! ! /* In colour modes, we have some bit-shuffling to do before */ ! /* we can print the data; in FS mode we also have the */ ! /* dithering to take care of. */ ! switch (ptype) { ! case DJ500C_COLOUR: ! ! /* Transpose the data to get pixel planes. */ ! for (i = 0, odp = plane_data[0]; i < buffer_size; ! i += 8, odp++) { /* The following is for 16-bit ! * machines */ ! #define spread3(c)\ ! { 0, c, c*0x100, c*0x101, c*0x10000L, c*0x10001L, c*0x10100L, c*0x10101L } ! static ulong spr40[8] = spread3(0x40); ! static ulong spr08[8] = spread3(8); ! static ulong spr02[8] = spread3(2); ! register byte *dp = data + i; ! register ulong pword = ! (spr40[dp[0]] << 1) + ! (spr40[dp[1]]) + ! (spr40[dp[2]] >> 1) + ! (spr08[dp[3]] << 1) + ! (spr08[dp[4]]) + ! (spr08[dp[5]] >> 1) + ! (spr02[dp[6]]) + ! (spr02[dp[7]] >> 1); ! odp[0] = (byte) (pword >> 16); ! odp[plane_size] = (byte) (pword >> 8); ! odp[plane_size * 2] = (byte) (pword); ! } ! break; ! case DJ500C_COLOUR_FS: ! if (going_up) { ! for (i = 0; i < plane_size; i++) { ! byte c, y, m, bitmask; ! int oldErr; ! ! bitmask = 0x80; ! for (c = m = y = j = 0; j < 8; j++) { ! FSdither(dp, c, ep, cErr, bitmask,, ++, -); ! FSdither(dp, m, ep, mErr, bitmask,, ++, -); ! FSdither(dp, y, ep, yErr, bitmask,, ++, -); ! bitmask >>= 1; ! } ! *cP++ = c; ! *mP++ = m; ! *yP++ = y; } + } else { /* going_down */ + for (i = 0; i < plane_size; i++) { + byte c, y, m, bitmask; + int oldErr; + + bitmask = 0x01; + for (c = m = y = j = 0; j < 8; j++) { + FSdither(dp, y, ep, yErr, bitmask, --,, +); + FSdither(dp, m, ep, mErr, bitmask, --,, +); + FSdither(dp, c, ep, cErr, bitmask, --,, +); + bitmask <<= 1; + } + *--cP = c; + *--mP = m; + *--yP = y; + } + } + going_up = !going_up; /* toggle scan direction */ + break; + } /* switch() DJET500C_COLOUR and DJET500C_COLOUR_FS */ + + /* Transfer raster graphics */ + /* in the order C, M, Y. */ + for (i = num_comps - 1; i >= 0; i--) { + + int out_count = gdev_pcl_mode9compress(plane_size, + plane_data[i], + prev_plane_data[i], + out_data); + + fprintf(prn_stream, "%d%c", out_count, "wvv"[i]); + fwrite(out_data, sizeof(byte), out_count, prn_stream); } ! } /* Printing non-blank lines */ ! } /* for lnum ... */ ! } /* send each scan line in turn */ ! /* end raster graphics */ ! fputs("\033*rbC", prn_stream); ! /* reset to monochrome */ ! fputs("\033*r1U", prn_stream); ! /* eject page */ ! fputs("\033&l0H", prn_stream); ! /* free temporary storage */ ! gs_free((char *) storage, storage_size_words, W, "hp_dj500c_print_page"); ! ! return 0; } + /* + * Mode 9 2D compression for the HP DeskJet 500C. This mode can give + * very good compression ratios, especially if there are areas of flat + * colour (or blank areas), and so is 'highly recommended' for colour + * printing in particular because of the very large amounts of data which + * can be generated + */ private int ! gdev_pcl_mode9compress(int bytecount, const byte * current, byte * previous, byte * compressed) { register const byte *cur = current; *************** *** 241,352 **** const byte *end = current + bytecount; ! while ( cur < end ) ! { /* Detect a run of unchanged bytes. */ ! const byte *run = cur; ! register const byte *diff; ! int offset; ! while ( cur < end && *cur == *prev ) ! { cur++, prev++; ! } ! if ( cur == end ) break; /* rest of row is unchanged */ ! /* Detect a run of changed bytes. */ ! /* We know that *cur != *prev. */ ! diff = cur; ! do ! { *prev++ = *cur++; } ! while ( cur < end && *cur != *prev ); ! /* Now [run..diff) are unchanged, and */ ! /* [diff..cur) are changed. */ ! offset = diff - run; ! { ! const byte *stop_test = cur - 4; ! int dissimilar, similar; ! ! while (diff < cur) { ! const byte *compr = diff; ! const byte *next; /* end of run */ ! byte value; ! while (diff <= stop_test && ! ((value = *diff) != diff[1] || ! value != diff[2] || ! value != diff[3])) ! diff++; ! ! /* Find out how long the run is */ ! if (diff > stop_test) /* no run */ ! next = diff = cur; ! else { ! next = diff + 4; ! while (next < cur && *next == value) ! next++; ! } ! #define MAXOFFSETU 15 #define MAXCOUNTU 7 ! /* output 'dissimilar' bytes, uncompressed */ ! if ((dissimilar = diff - compr)) ! { ! int temp, i; ! ! if ((temp = --dissimilar) > MAXCOUNTU) temp = MAXCOUNTU; ! if (offset < MAXOFFSETU) ! *out++ = (offset << 3) | (byte)temp; ! else { ! *out++ = (MAXOFFSETU << 3) | (byte)temp; ! offset -= MAXOFFSETU; ! while (offset >= 255) { ! *out++ = 255; ! offset -= 255; ! } ! *out++ = offset; ! } ! if (temp == MAXCOUNTU) { ! temp = dissimilar - MAXCOUNTU; ! while (temp >= 255) { ! *out++ = 255; ! temp -= 255; ! } ! *out++ = (byte)temp; ! } ! for (i = 0; i <= dissimilar; i++) *out++ = *compr++; ! offset = 0; ! } /* end uncompressed */ ! #define MAXOFFSETC 3 #define MAXCOUNTC 31 ! /* output 'similar' bytes, run-length endcoded */ ! if ((similar = next - diff)) ! { ! int temp; ! ! if ((temp = (similar -= 2)) > MAXCOUNTC) temp = MAXCOUNTC; ! if (offset < MAXOFFSETC) ! *out++ = 0x80 | (offset << 5) | (byte)temp; ! else { ! *out++ = 0x80 | (MAXOFFSETC << 5) | (byte)temp; ! offset -= MAXOFFSETC; ! while (offset >= 255) { ! *out++ = 255; ! offset -= 255; ! } ! *out++ = offset; ! } ! if (temp == MAXCOUNTC) { ! temp = similar - MAXCOUNTC; ! while (temp >= 255) { ! *out++ = 255; ! temp -= 255; ! } ! *out++ = (byte)temp; ! } ! *out++ = value; ! offset = 0; ! } /* end compressed */ ! ! diff = next; ! } } } return out - compressed; } --- 482,649 ---- const byte *end = current + bytecount; ! while (cur < end) { /* Detect a run of unchanged bytes. */ ! const byte *run = cur; ! register const byte *diff; ! int offset; ! while (cur < end && *cur == *prev) { ! cur++, prev++; ! } ! if (cur == end) ! break; /* rest of row is unchanged */ ! /* Detect a run of changed bytes. */ ! /* We know that *cur != *prev. */ ! diff = cur; ! do { ! *prev++ = *cur++; ! } ! while (cur < end && *cur != *prev); ! /* Now [run..diff) are unchanged, and */ ! /* [diff..cur) are changed. */ ! offset = diff - run; ! { ! const byte *stop_test = cur - 4; ! int dissimilar, similar; ! ! while (diff < cur) { ! const byte *compr = diff; ! const byte *next; /* end of run */ ! byte value; ! while (diff <= stop_test && ! ((value = *diff) != diff[1] || ! value != diff[2] || ! value != diff[3])) ! diff++; ! ! /* Find out how long the run is */ ! if (diff > stop_test) /* no run */ ! next = diff = cur; ! else { ! next = diff + 4; ! while (next < cur && *next == value) ! next++; } ! #define MAXOFFSETU 15 #define MAXCOUNTU 7 ! /* output 'dissimilar' bytes, uncompressed */ ! if ((dissimilar = diff - compr)) { ! int temp, i; ! ! if ((temp = --dissimilar) > MAXCOUNTU) ! temp = MAXCOUNTU; ! if (offset < MAXOFFSETU) ! *out++ = (offset << 3) | (byte) temp; ! else { ! *out++ = (MAXOFFSETU << 3) | (byte) temp; ! offset -= MAXOFFSETU; ! while (offset >= 255) { ! *out++ = 255; ! offset -= 255; ! } ! *out++ = offset; ! } ! if (temp == MAXCOUNTU) { ! temp = dissimilar - MAXCOUNTU; ! while (temp >= 255) { ! *out++ = 255; ! temp -= 255; ! } ! *out++ = (byte) temp; ! } ! for (i = 0; i <= dissimilar; i++) ! *out++ = *compr++; ! offset = 0; ! } /* end uncompressed */ #define MAXOFFSETC 3 #define MAXCOUNTC 31 ! /* output 'similar' bytes, run-length encoded */ ! if ((similar = next - diff)) { ! int temp; ! ! if ((temp = (similar -= 2)) > MAXCOUNTC) ! temp = MAXCOUNTC; ! if (offset < MAXOFFSETC) ! *out++ = 0x80 | (offset << 5) | (byte) temp; ! else { ! *out++ = 0x80 | (MAXOFFSETC << 5) | (byte) temp; ! offset -= MAXOFFSETC; ! while (offset >= 255) { ! *out++ = 255; ! offset -= 255; ! } ! *out++ = offset; ! } ! if (temp == MAXCOUNTC) { ! temp = similar - MAXCOUNTC; ! while (temp >= 255) { ! *out++ = 255; ! temp -= 255; ! } ! *out++ = (byte) temp; ! } ! *out++ = value; ! offset = 0; ! } /* end compressed */ ! diff = next; } } + } return out - compressed; } + + /* Map a r-g-b color to a color index. */ + /* We complement the colours, since we're using cmy anyway, */ + /* and because the buffering routines expect white to be zero. */ + private gx_color_index + gdev_pcl_true_map_rgb_color(gx_device * dev, gx_color_value r, + gx_color_value g, gx_color_value b) + { + if ((r & g & b) == 0xff) + return (gx_color_index)0; /* white */ + else + return (gx_color_value_to_byte(r) + + ((uint) gx_color_value_to_byte(g) << 8) + + ((ulong) gx_color_value_to_byte(b) << 16)) ^ 0xffffff; + } + + /* Map a color index to a r-g-b color. */ + /* Includes colour balancing, following HP recommendations, to try */ + /* and correct the greenish cast resulting from an equal mix of the */ + /* c, m, y, inks to give a truer black. */ + /* Someday we can add gamma-lookup tables as well */ + private int + gdev_pcl_true_map_color_rgb(gx_device * dev, gx_color_index color, + gx_color_value prgb[3]) + { + /* NB. We actually have cmy colours, from the way we set up the */ + /* mapping rgb_color */ + int c = (int)(color >> 16); + int m = (int)((color >> 8) & 0xff); + int y = (int)(color & 0xff); + if ((c & m & y) == 0) /* white */ + return 0; + else { + int maxval, minval, range; + + maxval = c >= m ? c : m; + maxval = maxval >= y ? maxval : y; + if (maxval > 0) { + minval = c <= m ? c : m; + minval = minval <= y ? minval : y; + range = maxval - minval; + + #define CORRECTION 4 /* ie. 4/5 reduction in cyan to get true black */ + c = ((long)(c << 1) + (range + (long)(maxval * CORRECTION)) + 1) / + (long)(maxval * ((CORRECTION + 1) << 1)); + + prgb[0] = (gx_color_value)c; + prgb[1] = (gx_color_value)m; + prgb[2] = (gx_color_value)y; + } + } + return 0; + } + + #undef t_margin + #undef b_margin + #undef height diff -rc2N gs241/gdevdfax.c gs25/gdevdfax.c *** gs241/gdevdfax.c Sat Mar 21 10:59:56 1992 --- gs25/gdevdfax.c Sat Apr 25 12:48:54 1992 *************** *** 268,272 **** if (filename) ! fp = fopen(filename, "w"); else fp = stdout; --- 268,272 ---- if (filename) ! fp = fopen(filename, "wb"); else fp = stdout; diff -rc2N gs241/gdevdjet.c gs25/gdevdjet.c *** gs241/gdevdjet.c Mon Apr 20 13:13:02 1992 --- gs25/gdevdjet.c Wed Aug 19 00:55:38 1992 *************** *** 1,3 **** ! /* Copyright (C) 1989, 1990, 1991 Aladdin Enterprises. All rights reserved. Distributed by Free Software Foundation, Inc. --- 1,3 ---- ! /* Copyright (C) 1989, 1992 Aladdin Enterprises. All rights reserved. Distributed by Free Software Foundation, Inc. *************** *** 24,28 **** /* Thanks to Jim Mayer, Xerox Webster Research Center, */ ! /* and to Jan-Mark Wams (jms@cs.vu.nl) for improvements. */ /* --- 24,29 ---- /* Thanks to Jim Mayer, Xerox Webster Research Center, */ ! /* and to Jan-Mark Wams (jms@cs.vu.nl) and Frans van Hoesel */ ! /* (hoesel@rugr86.rug.nl) for improvements. */ /* *************** *** 30,33 **** --- 31,37 ---- * Normally you would do this in the makefile or on the gs command line, * not here. + * + * If the preprocessor symbol A4 is defined, the default paper size is + * the European A4 size; otherwise it is the U.S. letter size (8.5"x11"). */ /*#define X_DPI 300*/ *************** *** 34,48 **** /*#define Y_DPI 300*/ - /* - * Standard U.S. page width and height. A4 paper is 8.4" x 11.7". - */ - #define WIDTH_10THS 85 - #define HEIGHT_10THS 110 - #define X_DPI_MAX 300 #define Y_DPI_MAX 300 ! /* We round up the LINE_SIZE to a multiple of a ulong for faster scanning. */ ! #define W sizeof(word) ! #define LINE_SIZE ((X_DPI_MAX * 85 / 10 + W * 8 - 1) / (W * 8) * W) #ifndef X_DPI # define X_DPI X_DPI_MAX --- 38,44 ---- /*#define Y_DPI 300*/ #define X_DPI_MAX 300 #define Y_DPI_MAX 300 ! #ifndef X_DPI # define X_DPI X_DPI_MAX *************** *** 52,55 **** --- 48,83 ---- #endif + /* + * For all DeskJet Printers: + * + * Maximum printing width = 2400 dots = 8" + * All Deskjets have 1/2" unprintable bottom margin + * + * Note that the margins defined just below here apply only to the DeskJet; + * the paper size, width and height apply to the LaserJet as well. + */ + + /* Margins are left, bottom, right, top. */ + #define DESKJET_MARGINS_LETTER 0.25, 0.40, 0.25, 0.40 + #define DESKJET_MARGINS_A4 0.15, 0.40, 0.15, 0.05 + + #ifndef A4 + # define WIDTH_10THS 85 + # define HEIGHT_10THS 110 + # define DESKJET_MARGINS DESKJET_MARGINS_LETTER + #else + # define WIDTH_10THS 83 /* 210mm */ + # define HEIGHT_10THS 117 /* 297mm */ + # define DESKJET_MARGINS DESKJET_MARGINS_A4 + #endif + + /* The number of blank lines that make it worthwhile to reposition */ + /* the cursor. */ + #define MIN_SKIP_LINES 7 + + /* We round up the LINE_SIZE to a multiple of a ulong for faster scanning. */ + #define W sizeof(word) + #define LINE_SIZE ((X_DPI_MAX * 85 / 10 + W * 8 - 1) / (W * 8) * W) + /* Printer types */ #define LJ 0 *************** *** 61,100 **** /* The printer initialization strings. */ ! private char *init_strings[] = { /* LaserJet PCL 3, no compression */ ! "\033*r0A\033&l0E\033*p0x0Y\033*b0M", /* LaserJet Plus PCL 3, no compression */ ! "\033*r0A\033&l0E\033*p0x0Y\033*b0M", /* LaserJet IIP PCL 4, mode 2 compression */ ! "\033*r0f0A\033&l0E\033&l-185U\033*p0x0Y\033*b2M", /* LaserJet III PCL 5, mode 2&3 compression */ ! "\033*r0f0A\033&l0E\033&l-185U\033*p0x0Y", /* DeskJet almost PCL 4, mode 2 compression */ ! /* Key to codes: set 8.5x11 paper; portrait orientation; */ ! /* bidirectional printing; no perf-skip; move to top left; */ ! /* start raster graphics; mode 2 compression. */ ! "\033&l2A\033&l0O\033&k1W\033&l0L\033*p0x0Y\033*r0A\033*b2M", /* DeskJet 500 almost PCL 4, mode 2&3 compression */ ! "\033&l2A\033&l0O\033&k1W\033&l0L\033*p0x0Y\033*r0A", ! }; ! ! /* The patterns for skipping blank lines. */ ! /* (These are all the same now, but I'm not 100% sure this is right.) */ ! private char *skip_patterns[] = { ! /* LaserJet PCL 3 */ ! "\033*p+%dY", ! /* LaserJet Plus PCL 3 */ ! "\033*p+%dY", ! /* LaserJet IIP PCL 4 */ ! "\033*p+%dY", ! /* LaserJet III PCL 5 */ ! "\033*p+%dY", ! /* DeskJet almost PCL 4 */ ! "\033*p+%dY", ! /* DeskJet 500 almost PCL 4 */ ! "\033*p+%dY" }; /* The device descriptors */ private dev_proc_print_page(djet_print_page); private dev_proc_print_page(djet500_print_page); --- 89,109 ---- /* The printer initialization strings. */ ! private const char *init_strings[] = { /* LaserJet PCL 3, no compression */ ! "\033*p0x0Y\033*b0M", /* LaserJet Plus PCL 3, no compression */ ! "\033*p0x0Y\033*b0M", /* LaserJet IIP PCL 4, mode 2 compression */ ! "\033*r0F\033*p0x75Y\033*b2M", /* LaserJet III PCL 5, mode 2&3 compression */ ! "\033*r0F\033*p0x75Y", /* DeskJet almost PCL 4, mode 2 compression */ ! "\033&k1W\033*p0x0Y\033*b2M", /* DeskJet 500 almost PCL 4, mode 2&3 compression */ ! "\033&k1W\033*p0x0Y", }; /* The device descriptors */ + private dev_proc_open_device(hpjet_open); private dev_proc_print_page(djet_print_page); private dev_proc_print_page(djet500_print_page); *************** *** 104,131 **** private dev_proc_print_page(ljet3_print_page); ! /* ! * HP printers need their own get_initial_matrix procedure. See the ! * definition of hp_get_initial_matrix for the reason why. ! */ ! private dev_proc_get_initial_matrix(hp_get_initial_matrix); ! ! /* See gdevprn.h and gdevprn.c to understand the NULL entries below. */ ! gx_device_procs prn_hp_procs = { ! gdev_prn_open, ! hp_get_initial_matrix, ! gx_default_sync_output, ! gdev_prn_output_page, ! gdev_prn_close, ! gdev_prn_map_rgb_color, ! gdev_prn_map_color_rgb, ! NULL, /* fill_rectangle */ ! NULL, /* tile_rectangle */ ! NULL, /* copy_mono */ ! NULL, /* copy_color */ ! NULL, /* draw_line */ ! NULL, /* get_bits */ ! gdev_prn_get_props, ! gdev_prn_put_props ! }; gx_device_printer gs_deskjet_device = --- 113,119 ---- private dev_proc_print_page(ljet3_print_page); ! gx_device_procs prn_hp_procs = ! prn_matrix_procs(hpjet_open, gdev_pcl_get_initial_matrix, ! gdev_prn_output_page, gdev_prn_close); gx_device_printer gs_deskjet_device = *************** *** 133,137 **** WIDTH_10THS, HEIGHT_10THS, X_DPI, Y_DPI, ! 0.25, 0.50, 0.25, 0.0625, /* margins */ 1, djet_print_page); --- 121,125 ---- WIDTH_10THS, HEIGHT_10THS, X_DPI, Y_DPI, ! 0, 0, 0, 0, /* margins filled in by hpjet_open */ 1, djet_print_page); *************** *** 140,144 **** WIDTH_10THS, HEIGHT_10THS, X_DPI, Y_DPI, ! 0.25, 0.50, 0.25, 0.0625, /* margins */ 1, djet500_print_page); --- 128,132 ---- WIDTH_10THS, HEIGHT_10THS, X_DPI, Y_DPI, ! 0, 0, 0, 0, /* margins filled in by hpjet_open */ 1, djet500_print_page); *************** *** 174,177 **** --- 162,187 ---- private int hpjet_print_page(P3(gx_device_printer *, FILE *, int)); + /* Open the printer, adjusting the margins if necessary. */ + private int + hpjet_open(gx_device *pdev) + { /* Change the margins if necessary. */ + #define ppdev ((gx_device_printer *)pdev) + if ( ppdev->print_page == djet_print_page || + ppdev->print_page == djet500_print_page + ) + #undef ppdev + { static const float m_a4[4] = { DESKJET_MARGINS_A4 }; + static const float m_letter[4] = { DESKJET_MARGINS_LETTER }; + const float _ds *m = + (gdev_pcl_paper_size(pdev) == PAPER_SIZE_A4 ? m_a4 : + m_letter); + pdev->l_margin = m[0]; + pdev->b_margin = m[1]; + pdev->r_margin = m[2]; + pdev->t_margin = m[3]; + } + return gdev_prn_open(pdev); + } + /* ------ Internal routines ------ */ *************** *** 210,214 **** /* since computer-to-printer communication time is often a bottleneck. */ private int ! hpjet_print_page(gx_device_printer *pdev, FILE *prn_stream, int compress) { int line_size = gdev_mem_bytes_per_scan_line((gx_device *)pdev); int line_size_words = (line_size + W - 1) / W; --- 220,224 ---- /* since computer-to-printer communication time is often a bottleneck. */ private int ! hpjet_print_page(gx_device_printer *pdev, FILE *prn_stream, int ptype) { int line_size = gdev_mem_bytes_per_scan_line((gx_device *)pdev); int line_size_words = (line_size + W - 1) / W; *************** *** 227,234 **** char *out_data; int x_dpi = pdev->x_pixels_per_inch; int out_count; int compression = -1; ! if ( storage == 0 ) return -1; /* can't allocate working area */ data_words = storage; out_row_words = data_words + (line_size_words * 2); --- 237,251 ---- char *out_data; int x_dpi = pdev->x_pixels_per_inch; + int y_dots_per_pixel = Y_DPI_MAX / pdev->y_pixels_per_inch; int out_count; int compression = -1; + static const char from2to3[] = "\033*rB\033*r1A\033*b3m"; + int penalty_from2to3 = strlen(from2to3); + static const char from3to2[] = "\033*rB\033*r1A\033*b2m"; + int penalty_from3to2 = strlen(from3to2); + int paper_size = gdev_pcl_paper_size((gx_device *)pdev); ! if ( storage == 0 ) /* can't allocate working area */ ! return_error(gs_error_VMerror); data_words = storage; out_row_words = data_words + (line_size_words * 2); *************** *** 242,246 **** fputs("\033*rB", prn_stream); /* end raster graphics */ fprintf(prn_stream, "\033*t%dR", x_dpi); /* set resolution */ ! fputs(init_strings[compress], prn_stream); /* Send each scan line in turn */ --- 259,269 ---- fputs("\033*rB", prn_stream); /* end raster graphics */ fprintf(prn_stream, "\033*t%dR", x_dpi); /* set resolution */ ! /* If the printer supports it, set the paper size */ ! /* based on the actual requested size. */ ! if ( !(ptype == LJ || ptype == LJplus) ) ! { fprintf(prn_stream, "\033&l%dA", paper_size); ! } ! fputs("\033&l0o0e0L", prn_stream); ! fputs(init_strings[ptype], prn_stream); /* Send each scan line in turn */ *************** *** 248,254 **** int num_blank_lines = 0; word rmask = ~(word)0 << (-pdev->width & (W * 8 - 1)); ! /* look for top margin white space... You would think that ! the normal (raster) white space mechanism would work... it ! doesn't... Sometimes PCL printers are brain-dead */ for ( lnum = 0; lnum < pdev->height; lnum++ ) { register word *end_data = data_words + line_size_words; --- 271,276 ---- int num_blank_lines = 0; word rmask = ~(word)0 << (-pdev->width & (W * 8 - 1)); ! ! /* Transfer raster graphics. */ for ( lnum = 0; lnum < pdev->height; lnum++ ) { register word *end_data = data_words + line_size_words; *************** *** 261,286 **** end_data--; if ( end_data == data_words ) - /* Blank line */ - num_blank_lines++; - else - break; - } - /* Skip blank lines if any */ - if ( num_blank_lines > 0 ) - { /* move down from current position */ - fprintf(prn_stream,"\033*p+%dY", num_blank_lines); - num_blank_lines = 0; - } - /* transfer raster graphics */ - for ( ; lnum < pdev->height; lnum++ ) - { register word *end_data = data_words + line_size_words; - gdev_prn_copy_scan_lines(pdev, lnum, - (byte *)data, line_size); - /* Mask off 1-bits beyond the line width. */ - end_data[-1] &= rmask; - /* Remove trailing 0s. */ - while ( end_data > data_words && end_data[-1] == 0 ) - end_data--; - if ( end_data == data_words ) { /* Blank line */ num_blank_lines++; --- 283,286 ---- *************** *** 287,291 **** continue; } ! switch (compress) { case LJ3: --- 287,328 ---- continue; } ! ! /* We've reached a non-blank line. */ ! /* Put out a spacing command if necessary. */ ! if ( num_blank_lines == lnum ) ! { /* We're at the top of a page. */ ! if ( num_blank_lines > 0 ) ! { /* move down from current position */ ! fprintf(prn_stream, "\033*p+%dY", ! num_blank_lines * y_dots_per_pixel); ! } ! /* Start raster graphics. */ ! fputs("\033*r1A", prn_stream); ! } ! /* Skip blank lines if any */ ! else if ( num_blank_lines != 0 ) ! { /* If we can do mode 3 compression, */ ! /* clear our record of the seed row. */ ! memset(prev_row, 0, line_size); ! if ( num_blank_lines < MIN_SKIP_LINES ) ! { /* Moving down from current position */ ! /* causes head motion on the DeskJet, so */ ! /* if the number of lines is small, */ ! /* we're better off printing blanks. */ ! /* Make sure we clear the seed row. */ ! fputs("\033*by0", prn_stream); ! for ( ; num_blank_lines > 1; num_blank_lines-- ) ! fputs("w", prn_stream); ! fputs("W", prn_stream); ! } ! else ! { fprintf(prn_stream, "\033*b%dY", num_blank_lines); ! } ! } ! num_blank_lines = 0; ! ! /* Choose the best compression mode */ ! /* for this particular line. */ ! switch (ptype) { case LJ3: *************** *** 298,306 **** int count2 = gdev_pcl_mode2compress(data_words, end_data, out_row_alt); ! int penalty3 = (compression == 3 ? 0 : 5); ! int penalty2 = (compression == 2 ? 0 : 5); if ( count3 + penalty3 < count2 + penalty2) { if ( compression != 3 ) ! fputs("\033*b3M", prn_stream); compression = 3; out_data = out_row; --- 335,348 ---- int count2 = gdev_pcl_mode2compress(data_words, end_data, out_row_alt); ! /* The switching penalty is quite large, */ ! /* because PCL demands that we end raster */ ! /* graphics and start it again.... */ ! int penalty3 = ! (compression == 3 ? 0 : penalty_from2to3); ! int penalty2 = ! (compression == 2 ? 0 : penalty_from3to2); if ( count3 + penalty3 < count2 + penalty2) { if ( compression != 3 ) ! fputs(from2to3, prn_stream); compression = 3; out_data = out_row; *************** *** 309,313 **** else { if ( compression != 2 ) ! fputs("\033*b2M", prn_stream); compression = 2; out_data = out_row_alt; --- 351,355 ---- else { if ( compression != 2 ) ! fputs(from3to2, prn_stream); compression = 2; out_data = out_row_alt; *************** *** 326,339 **** out_count = (char *)end_data - data; } ! /* Skip blank lines if any */ ! if ( num_blank_lines > 0 ) ! { /* move down from current position */ ! fprintf(prn_stream, skip_patterns[compress], ! num_blank_lines); ! num_blank_lines = 0; ! } ! /* transfer raster graphics */ fprintf(prn_stream, "\033*b%dW", out_count); - /* send the row */ fwrite(out_data, sizeof(char), out_count, prn_stream); --- 368,374 ---- out_count = (char *)end_data - data; } ! ! /* Transfer the data */ fprintf(prn_stream, "\033*b%dW", out_count); fwrite(out_data, sizeof(char), out_count, prn_stream); *************** *** 351,372 **** return 0; - } - - - /* - * PCL has the notion of a LOGICAL and a PHYSICAL page. The PHYSICAL page is - * the actual paper; the LOGICAL page is the printer specific imageable area. - * The strange part is that coordinates are all relative to the - * LOGICAL page. This means that all PCL code is inherently device dependent. - * Luckily, in PostScript land, transformation matrices conquer all. - */ - - private void - hp_get_initial_matrix(gx_device *dev, gs_matrix *pmat) - { pmat->xx = dev->x_pixels_per_inch / 72.0; - pmat->xy = 0; - pmat->yx = 0; - pmat->yy = dev->y_pixels_per_inch / -72.0; - pmat->tx = -(dev->l_margin * dev->x_pixels_per_inch); - pmat->ty = dev->height - (dev->t_margin * dev->y_pixels_per_inch); } --- 386,388 ---- diff -rc2N gs241/gdevdjtc.c gs25/gdevdjtc.c *** gs241/gdevdjtc.c Mon Mar 23 17:16:06 1992 --- gs25/gdevdjtc.c Sat Jul 25 09:05:40 1992 *************** *** 27,30 **** --- 27,38 ---- *** please contact AKayser@et.tudelft.nl if you have questions. ***/ + + #ifndef SHINGLING /* Interlaced, multi-pass printing */ + #define SHINGLING 1 /* 0 = none, 1 = 50%, 2 = 25%, 2 is best & slowest */ + #endif + + #ifndef DEPLETION /* 'Intelligent' dot-removal */ + #define DEPLETION 1 /* 0 = none, 1 = 25%, 2 = 50%, 1 best for graphics? */ + #endif /* Use 0 for transparencies */ #define X_DPI 300 *************** *** 42,50 **** gx_device_printer gs_djet500c_device = prn_device(djet500c_procs, "djet500c", ! 85, /* width_10ths, 8.5" */ ! 120, /* height_10ths, 12" */ ! X_DPI, Y_DPI, ! 0.25, 0.25, 0.25, 0.25, /* margins */ ! 3, djet500c_print_page); /* Forward references */ --- 50,58 ---- gx_device_printer gs_djet500c_device = prn_device(djet500c_procs, "djet500c", ! 85, /* width_10ths, 8.5" */ ! 120, /* height_10ths, 12" */ ! X_DPI, Y_DPI, ! 0.25, 0.25, 0.25, 0.25, /* margins */ ! 3, djet500c_print_page); /* Forward references */ *************** *** 51,54 **** --- 59,64 ---- private int djet500c_print_page(P2(gx_device_printer *, FILE *)); + static int mode2compress(P3(byte *row, byte *end_row, byte *compressed)); + /* The DeskJet 500C uses additive colors in separate planes. */ /* We only keep one bit of color, with 1 = R, 2 = G, 4 = B. */ *************** *** 55,81 **** /* Because the buffering routines assume 0 = white, */ /* we complement all the color components. */ - #define cv_shift (sizeof(gx_color_value) * 8 - 1) - - /* Map an RGB color to a printer color. */ - private gx_color_index - djet500c_map_rgb_color(gx_device *dev, gx_color_value r, gx_color_value g, - gx_color_value b) - { return (((b >> cv_shift) << 2) + ((g >> cv_shift) << 1) + (r >> cv_shift)) ^ 7; - } - - /* Map the printer color back to RGB. */ - private int - djet500c_map_color_rgb(gx_device *dev, gx_color_index color, - gx_color_value prgb[3]) - { ushort cc = (ushort)color ^ 7; - prgb[0] = -(cc & 1); - prgb[1] = -((cc >> 1) & 1); - prgb[2] = -(cc >> 2); - return 0; - } /* Send the page to the printer. For speed, compress each scan line, */ /* since computer-to-printer communication time is often a bottleneck. */ ! /* The DeskJet Color can compress (mode 3) */ private int --- 65,72 ---- /* Because the buffering routines assume 0 = white, */ /* we complement all the color components. */ /* Send the page to the printer. For speed, compress each scan line, */ /* since computer-to-printer communication time is often a bottleneck. */ ! /* The DeskJet Color can compress (mode 2) */ private int *************** *** 82,172 **** djet500c_print_page(gx_device_printer *pdev, FILE *fprn) { ! #define DATA_SIZE (LINE_SIZE*8) ! byte data[DATA_SIZE]; ! byte plane_data[DATA_SIZE]; ! ! /* select the most compressed mode available & clear tmp storage */ ! /* put printer in known state */ ! fputs("\033E",fprn); ! /* ends raster graphics to set raster graphics resolution */ ! fputs("\033*rbC", fprn); /* was \033*rB */ ! ! /* set raster graphics resolution -- 300 dpi */ ! fputs("\033*t300R", fprn); ! /* move to top left of page & set current position */ ! fputs("\033*p0x0Y", fprn); /* cursor pos: 0,0 */ ! fputs("\033*r0A", fprn); /* start graf. left */ ! fputs("\033*b2M", fprn); /* mode 3 compression for now */ ! fputs("\033*r3U", fprn); /* RGB Mode */ ! fputs("\033&l26a0l1H", fprn); /* A4, skip perf, def. paper tray */ ! ! /* Send each scan line in turn */ ! { int lnum; ! int line_size = gdev_mem_bytes_per_scan_line((gx_device *)pdev); ! int num_blank_lines = 0; ! for (lnum=0; lnumheight; lnum++) ! { ! byte _ss *end_data = data + line_size; ! gdev_prn_copy_scan_lines(pdev, lnum, (byte *)data, line_size); ! ! /* Remove trailing 0s. */ ! while ( end_data > data && end_data[-1] == 0 ) ! end_data--; ! if ( end_data == data ) ! num_blank_lines++; ! else ! { int i; ! byte _ss *odp; ! byte _ss *row; ! ! /* Pad with 0s to fill out the last */ ! /* block of 8 bytes. */ ! memset(end_data, 0, 7); ! ! /* Transpose the data to get pixel planes. */ ! for (i=0, odp=plane_data; i>1) ^ 0xff; ! odp[LINE_SIZE*2] = (byte)(b>>2) ^ 0xff; ! } ! ! /* Skip blank lines if any */ ! if ( num_blank_lines > 0 ) ! { /* move down from current position */ ! fprintf(fprn, "\033*b%dY", num_blank_lines); ! num_blank_lines = 0; ! } ! ! /* Transfer raster graphics */ ! /* in the order R, G, B. */ ! row=plane_data+LINE_SIZE*2; ! for (i=0; i<3; row-=LINE_SIZE,i++) ! { ! byte temp[LINE_SIZE * 2]; ! int count = gdev_pcl_mode2compress((word *)row, (word *)(row + LINE_SIZE), temp); ! fprintf(fprn, "\033*b%d%c", count, "VVW"[i]); ! fwrite(temp, sizeof(byte), count, fprn); ! } ! } ! } ! } ! /* end raster graphics */ ! fputs("\033*rbC", fprn); /* was \033*rB */ ! fputs("\033*r1U", fprn); /* back to 1 plane */ ! ! /* put printer in known state */ ! fputs("\033E",fprn); ! ! /* eject page */ ! fputs("\033&l0H", fprn); ! return 0; } --- 73,276 ---- djet500c_print_page(gx_device_printer *pdev, FILE *fprn) { ! byte *bitData=NULL; ! byte *plane1=NULL; ! byte *plane2=NULL; ! byte *plane3=NULL; ! int bitSize=0; ! int planeSize=0; ! ! /* select the most compressed mode available & clear tmp storage */ ! /* put printer in known state */ ! fputs("\033E",fprn); ! ! /* ends raster graphics to set raster graphics resolution */ ! fputs("\033*rbC", fprn); /* was \033*rB */ ! ! /* set raster graphics resolution -- 300 dpi */ ! fputs("\033*t300R", fprn); ! ! /* A4, skip perf, def. paper tray */ ! fputs("\033&l26a0l1H", fprn); ! ! /* RGB Mode */ ! fputs("\033*r3U", fprn); ! ! /* set depletion level */ ! fprintf(fprn, "\033*o%dD", DEPLETION); ! ! /* set shingling level */ ! fprintf(fprn, "\033*o%dQ", SHINGLING); ! ! /* move to top left of page & set current position */ ! fputs("\033*p0x0Y", fprn); /* cursor pos: 0,0 */ ! ! fputs("\033*b2M", fprn); /* mode 2 compression for now */ ! ! fputs("\033*r0A", fprn); /* start graf. left */ ! ! /* Send each scan line in turn */ ! { int lnum; ! int num_blank_lines = 0; ! int lineSize = gdev_mem_bytes_per_scan_line((gx_device *)pdev); ! if (lineSize>bitSize) ! { ! if (bitData) free(bitData); ! bitSize=lineSize; ! bitData=(byte*)malloc(bitSize+16); ! } ! for (lnum=0; lnumheight; lnum++) ! { ! byte *endData; ! ! gdev_prn_copy_scan_lines(pdev, lnum, bitData, lineSize); ! ! /* Remove trailing 0s. */ ! endData = bitData + lineSize; ! while ( (endData>bitData) && (endData[-1] == 0) ) ! endData--; ! if (endData == bitData) ! num_blank_lines++; ! else ! { int count, k, i, lineLen; ! ! /* Pad with 0s to fill out the last */ ! /* block of 8 bytes. */ ! memset(endData, 0, 7); ! ! lineLen=((endData-bitData)+7)/8; /* Round to next 8multiple */ ! if (planeSize>2); ! for (c=t=0;t<8;t++) ! c = (c<<1) | (bitData[t+i]&2); ! plane2[k] = ~(byte)(c>>1); ! for (c=t=0;t<8;t++) ! c = (c<<1) | (bitData[t+i]&1); ! plane1[k] = ~(byte)(c); ! } ! ! /* Skip blank lines if any */ ! if (num_blank_lines > 0) ! { /* move down from current position */ ! fprintf(fprn, "\033*b%dY", num_blank_lines); ! num_blank_lines = 0; ! } ! ! /* Transfer raster graphics */ ! /* in the order R, G, B. */ ! /* lineLen is at least bitSize/8, so bitData can easily be used to store ! lineLen of bytes */ ! /* P.s. mode9 compression is akward(??) to use, because the lineLenght's ! are different, so we are stuck with mode 2, which is good enough */ ! ! /* set the line width */ ! fprintf(fprn, "\033*r%dS", lineLen*8); ! ! count = mode2compress(plane1, plane1 + lineLen, bitData); ! fprintf(fprn, "\033*b%dV", count); ! fwrite(bitData, sizeof(byte), count, fprn); ! count = mode2compress(plane2, plane2 + lineLen, bitData); ! fprintf(fprn, "\033*b%dV", count); ! fwrite(bitData, sizeof(byte), count, fprn); ! count = mode2compress(plane3, plane3 + lineLen, bitData); ! fprintf(fprn, "\033*b%dW", count); ! fwrite(bitData, sizeof(byte), count, fprn); ! } ! } ! } ! /* end raster graphics */ ! fputs("\033*rbC", fprn); /* was \033*rB */ ! fputs("\033*r1U", fprn); /* back to 1 plane */ ! ! /* put printer in known state */ ! fputs("\033E",fprn); ! ! /* eject page */ ! fputs("\033&l0H", fprn); ! ! /* release allocated memory */ ! if (bitData) free(bitData); ! if (plane1) free(plane1); ! if (plane2) free(plane2); ! if (plane3) free(plane3); ! ! return 0; ! } ! ! /* ! * Mode 2 Row compression routine for the HP DeskJet & LaserJet IIp. ! * Compresses data from row up to end_row, storing the result ! * starting at compressed. Returns the number of bytes stored. ! * Runs of K<=127 literal bytes are encoded as K-1 followed by ! * the bytes; runs of 2<=K<=127 identical bytes are encoded as ! * 257-K followed by the byte. ! * In the worst case, the result is N+(N/127)+1 bytes long, ! * where N is the original byte count (end_row - row). ! * I can't use the general pcl version, because it assume even linelength's ! */ ! ! static int ! mode2compress(byte *row, byte *end_row, byte *compressed) ! { ! register byte *exam; /* word being examined in the row to compress */ ! register byte *cptr = compressed; /* output pointer into compressed bytes */ ! int i, count, len; ! byte test; ! ! exam = row; ! while (1) ! { ! test = *exam++; ! /* Advance exam until test==*exam or exam==end_row */ ! while ((test!=*exam) && (exam0) ! { ! count=len; ! if (count>127) count=127; ! *cptr++=count-1; ! for (i=0;i=end_row) break; /* done */ ! exam++; /* skip first same byte */ ! while ((test==*exam) && (exam0) ! { ! count=len; ! if (count>127) count=127; ! *cptr++=(257-count); ! *cptr++=test; ! len-=count; ! } ! if (exam>=end_row) break; /* end of data */ ! row = exam; /* row points to first dissimular byte */ ! } ! return (cptr-compressed); } diff -rc2N gs241/gdevegaa.asm gs25/gdevegaa.asm *** gs241/gdevegaa.asm Sun Jan 26 05:11:06 1992 --- gs25/gdevegaa.asm Fri Apr 24 12:58:22 1992 *************** *** 1,3 **** ! ; Copyright (C) 1989, 1990, 1991 Aladdin Enterprises. All rights reserved. ; Distributed by Free Software Foundation, Inc. ; --- 1,3 ---- ! ; Copyright (C) 1989, 1992 Aladdin Enterprises. All rights reserved. ; Distributed by Free Software Foundation, Inc. ; *************** *** 66,70 **** p_dest equ 0 ; fb_ptr dest; /* pointer to frame buffer */ p_draster equ 4 ; int draster; /* raster of frame buffer */ ! p_src equ 6 ; byte far *src; /* pointer to source data */ p_sraster equ 10 ; int sraster; /* source raster */ p_width equ 12 ; int width; /* width in bytes */ --- 66,70 ---- p_dest equ 0 ; fb_ptr dest; /* pointer to frame buffer */ p_draster equ 4 ; int draster; /* raster of frame buffer */ ! p_src equ 6 ; const byte far *src; /* pointer to source data */ p_sraster equ 10 ; int sraster; /* source raster */ p_width equ 12 ; int width; /* width in bytes */ *************** *** 174,178 **** ; void memrwcol(rop_params _ss *rop) ! ; { byte far *dp = rop->dest, *sp = rop->src; ; int yc = rop->height; ; int shift = rop->shift; --- 174,179 ---- ; void memrwcol(rop_params _ss *rop) ! ; { byte far *dp = rop->dest; ! ; const byte far *sp = rop->src; ; int yc = rop->height; ; int shift = rop->shift; *************** *** 227,231 **** ; void memrwcol2(rop_params _ss *rop) ! ; { byte far *dp = rop->dest, *sp = rop->src; ; int yc = rop->height; ; int shift = rop->shift; --- 228,233 ---- ; void memrwcol2(rop_params _ss *rop) ! ; { byte far *dp = rop->dest; ! ; const byte far *sp = rop->src; ; int yc = rop->height; ; int shift = rop->shift; diff -rc2N gs241/gdevepsn.c gs25/gdevepsn.c *** gs241/gdevepsn.c Wed Nov 27 02:08:10 1991 --- gs25/gdevepsn.c Sun Aug 2 14:16:12 1992 *************** *** 1,3 **** ! /* Copyright (C) 1989, 1990, 1991 Aladdin Enterprises. All rights reserved. Distributed by Free Software Foundation, Inc. --- 1,3 ---- ! /* Copyright (C) 1989-1992 Aladdin Enterprises. All rights reserved. Distributed by Free Software Foundation, Inc. *************** *** 19,56 **** /* gdevepsn.c */ ! /* Epson dot-matrix printer driver for Ghostscript */ #include "gdevprn.h" - /************************************************ - * For 9-pin printers, you may select - * X_DPI = 60, 120, or 240 - * Y_DPI = 60 or 72 - * For 24-pin printers, you may select - * X_DPI = 60, 120, 180, 240, or 360 - * Y_DPI = 60, 72, 180, or 216 - * Note that a given printer implements *either* Y_DPI = 60 | 180 *or* - * Y_DPI = 72 | 216; no attempt is made to check this here. - * Note that X_DPI = 180 or 360 requires Y_DPI > 100; - * this isn't checked either. Finally, note that X_DPI=240 and - * X_DPI=360 are double-density modes requiring two passes to print. - * - * The values of X_DPI and Y_DPI may be set at compile time: - * see gdevs.mak. - * - * At some time in the future, we could simulate 24-bit output on - * 9-pin printers by using fractional vertical positioning; - * we could even implement an X_DPI=360 mode by using the - * ESC++ command that spaces vertically in units of 1/360" - * (not supported on many printers.) - ************************************************/ #ifndef X_DPI ! # define X_DPI 240 /* pixels per inch */ #endif #ifndef Y_DPI ! # define Y_DPI 60 /* pixels per inch */ #endif /* The device descriptors */ ! private dev_proc_print_page(eps_print_page); gx_device_printer gs_epson_device = prn_device(prn_std_procs, "epson", --- 19,72 ---- /* gdevepsn.c */ ! /* ! * Epson dot-matrix printer driver for Ghostscript. ! * ! * Two devices are defined here: 'epson' and 'eps9high'. The 'epson' device ! * is the generic device, for 9-pin and 24-pin printers. 'eps9high' is ! * a special mode for 9-pin printers where scan lines are interleaved in ! * multiple passes to produce high vertical resolution at the expense of ! * several passes of the print head. ! * ! * Thanks to David Wexelblat (dwex@mtgzfs3.att.com) for the 'eps9high' code. ! */ #include "gdevprn.h" + /* + * Valid values for X_DPI: + * + * For 9-pin printers: 60, 120, 240 + * For 24-pin printers: 60, 120, 180, 240, 360 + * + * The value specified at compile time is the default value used if the + * user does not specify a resolution at runtime. + */ #ifndef X_DPI ! # define X_DPI 240 ! #endif ! ! /* ! * For Y_DPI, a given printer will support a base resolution of 60 or 72; ! * check the printer manual. The Y_DPI value must be a multiple of this ! * base resolution. Valid values for Y_DPI: ! * ! * For 9-pin printers: 1*base_res ! * For 24-pin printers: 1*base_res, 3*base_res ! * ! * The value specified at compile time is the default value used if the ! * user does not specify a resolution at runtime. ! */ ! ! #ifndef Y_BASERES ! # define Y_BASERES 72 #endif #ifndef Y_DPI ! # define Y_DPI (1*Y_BASERES) #endif /* The device descriptors */ ! private dev_proc_print_page(eps_print_page1); ! private dev_proc_print_page(eps_print_page2); ! ! /* Standard Epson device */ gx_device_printer gs_epson_device = prn_device(prn_std_procs, "epson", *************** *** 59,63 **** X_DPI, Y_DPI, 0, 0, 0.5, 0, /* margins */ ! 1, eps_print_page); /* ------ Internal routines ------ */ --- 75,88 ---- X_DPI, Y_DPI, 0, 0, 0.5, 0, /* margins */ ! 1, eps_print_page1); ! ! /* High-res (interleaved) 9-pin device */ ! gx_device_printer gs_eps9high_device = ! prn_device(prn_std_procs, "eps9high", ! 85, /* width_10ths, 8.5" */ ! 110, /* height_10ths, 11" */ ! X_DPI, 3*Y_BASERES, ! 0, 0, 0.5, 0, /* margins */ ! 1, eps_print_page2); /* ------ Internal routines ------ */ *************** *** 69,87 **** #define DD 0x80 /* double density flag */ private int ! eps_print_page(gx_device_printer *pdev, FILE *prn_stream) ! { static char graphics_modes_9[5] = ! { -1, 0 /*60*/, 1 /*120*/, -1, DD+3 /*240*/ ! }; ! static char graphics_modes_24[7] = ! { -1, 32 /*60*/, 33 /*120*/, 39 /*180*/, ! -1, -1, DD+40 /*360*/ ! }; ! int y_24pin = pdev->y_pixels_per_inch > 72; ! int y_mult = (y_24pin ? 3 : 1); int line_size = gdev_mem_bytes_per_scan_line((gx_device *)pdev); ! int in_size = line_size * (8 * y_mult); ! byte *in = (byte *)gs_malloc(in_size, 1, "eps_print_page(in)"); ! int out_size = ((pdev->width + 7) & -8) * y_mult; ! byte *out = (byte *)gs_malloc(out_size, 1, "eps_print_page(out)"); int x_dpi = pdev->x_pixels_per_inch; char start_graphics = --- 94,120 ---- #define DD 0x80 /* double density flag */ private int ! eps_print_page(gx_device_printer *pdev, FILE *prn_stream, int y_9pin_high) ! { ! static const char graphics_modes_9[5] = ! { ! -1, 0 /*60*/, 1 /*120*/, -1, DD+3 /*240*/ ! }; ! ! static const char graphics_modes_24[7] = ! { ! -1, 32 /*60*/, 33 /*120*/, 39 /*180*/, ! -1, -1, DD+40 /*360*/ ! }; ! ! int y_24pin = (y_9pin_high ? 0 : pdev->y_pixels_per_inch > 72); ! int in_y_mult = ((y_24pin | y_9pin_high) ? 3 : 1); int line_size = gdev_mem_bytes_per_scan_line((gx_device *)pdev); ! /* Note that in_size is a multiple of 8. */ ! int in_size = line_size * (8 * in_y_mult); ! byte *buf1 = (byte *)gs_malloc(in_size, 1, "eps_print_page(buf1)"); ! byte *buf2 = (byte *)gs_malloc(in_size, 1, "eps_print_page(buf2)"); ! byte *in = buf1; ! byte *out = buf2; ! int out_y_mult = (y_24pin ? 3 : 1); int x_dpi = pdev->x_pixels_per_inch; char start_graphics = *************** *** 89,102 **** int first_pass = (start_graphics & DD ? 1 : 0); int last_pass = first_pass * 2; int dots_per_space = x_dpi / 10; /* pica space = 1/10" */ ! int bytes_per_space = dots_per_space * y_mult; ! int skip = 0, lnum = 0, pass; /* Check allocations */ ! if ( in == 0 || out == 0 ) ! { if ( in ) gs_free((char *)in, in_size, 1, "eps_print_page(in)"); ! if ( out ) gs_free((char *)out, out_size, 1, "eps_print_page(out)"); ! return -1; ! } /* Initialize the printer and reset the margins. */ --- 122,138 ---- int first_pass = (start_graphics & DD ? 1 : 0); int last_pass = first_pass * 2; + int y_passes = (y_9pin_high ? 3 : 1); int dots_per_space = x_dpi / 10; /* pica space = 1/10" */ ! int bytes_per_space = dots_per_space * out_y_mult; ! int skip = 0, lnum = 0, pass, ypass; /* Check allocations */ ! if ( buf1 == 0 || buf2 == 0 ) ! { if ( buf1 ) ! gs_free((char *)buf1, in_size, 1, "eps_print_page(buf1)"); ! if ( buf2 ) ! gs_free((char *)buf2, in_size, 1, "eps_print_page(buf2)"); ! return_error(gs_error_VMerror); ! } /* Initialize the printer and reset the margins. */ *************** *** 107,113 **** /* Print lines of graphics */ while ( lnum < pdev->height ) ! { byte *inp = in; ! byte *in_end = in + line_size; ! byte *out_end = out; byte *out_blk; register byte *outp; --- 143,150 ---- /* Print lines of graphics */ while ( lnum < pdev->height ) ! { ! byte *inp; ! byte *in_end; ! byte *out_end; byte *out_blk; register byte *outp; *************** *** 119,141 **** !memcmp((char *)in, (char *)in + 1, line_size - 1) ) ! { lnum++; ! skip += 3 / y_mult; continue; ! } /* Vertical tab to the appropriate position. */ while ( skip > 255 ) ! { fputs("\033J\377", prn_stream); skip -= 255; ! } if ( skip ) fprintf(prn_stream, "\033J%c", skip); /* Copy the rest of the scan lines. */ ! lcnt = 1 + gdev_prn_copy_scan_lines(pdev, lnum + 1, in + line_size, in_size - line_size); ! if ( lcnt < 8 * y_mult ) ! memset(in + lcnt * line_size, 0, ! in_size - lcnt * line_size); ! /* We have to 'transpose' blocks of 8 pixels x 8 lines, */ /* because that's how the printer wants the data. */ --- 156,211 ---- !memcmp((char *)in, (char *)in + 1, line_size - 1) ) ! { ! lnum++; ! skip += 3 / in_y_mult; continue; ! } /* Vertical tab to the appropriate position. */ while ( skip > 255 ) ! { ! fputs("\033J\377", prn_stream); skip -= 255; ! } if ( skip ) + { fprintf(prn_stream, "\033J%c", skip); + } /* Copy the rest of the scan lines. */ ! lcnt = 1 + gdev_prn_copy_scan_lines(pdev, lnum + 1, ! in + line_size, ! in_size - line_size); ! if ( lcnt < 8 * in_y_mult ) ! { /* Pad with lines of zeros. */ ! memset(in + lcnt * line_size, 0, ! in_size - lcnt * line_size); ! } ! ! if ( y_9pin_high ) ! { /* Shuffle the scan lines */ ! byte *p; ! int i; ! static const char index[] = ! { 0, 8, 16, 1, 9, 17, ! 2, 10, 18, 3, 11, 19, ! 4, 12, 20, 5, 13, 21, ! 6, 14, 22, 7, 15, 23 ! }; ! ! for ( i = 0; i < 24; i++ ) ! { ! memcpy(out+(index[i]*line_size), ! in+(i*line_size), line_size); ! } ! p = in; ! in = out; ! out = p; ! } ! ! for ( ypass = 0; ypass < y_passes; ypass++ ) ! { ! for ( pass = first_pass; pass <= last_pass; pass++ ) ! { /* We have to 'transpose' blocks of 8 pixels x 8 lines, */ /* because that's how the printer wants the data. */ *************** *** 143,174 **** /* groups of 3 lines at a time. */ ! if ( y_24pin ) ! { for ( ; inp < in_end; inp++, out_end += 24 ) ! { gdev_prn_transpose_8x8(inp, line_size, out_end, 3); ! gdev_prn_transpose_8x8(inp + line_size * 8, line_size, out_end + 1, 3); ! gdev_prn_transpose_8x8(inp + line_size * 16, line_size, out_end + 2, 3); ! } ! /* Remove trailing 0s. */ ! while ( out_end > out && out_end[-1] == 0 && ! out_end[-2] == 0 && out_end[-3] == 0 ! ) ! out_end -= 3; ! } ! else ! { for ( ; inp < in_end; inp++, out_end += 8 ) ! { gdev_prn_transpose_8x8(inp, line_size, out_end, 1); ! } ! /* Remove trailing 0s. */ ! while ( out_end > out && out_end[-1] == 0 ) ! out_end--; ! } - for ( pass = first_pass; pass <= last_pass; pass++ ) - { for ( out_blk = outp = out; outp < out_end; ) ! { /* Skip a run of leading 0s. */ ! /* At least 10 are needed to make tabbing worth it. */ ! /* We do everything by 3's to avoid having to make */ ! /* different cases for 9- and 24-pin. */ if ( *outp == 0 && outp + 12 <= out_end && --- 213,261 ---- /* groups of 3 lines at a time. */ ! if ( pass == first_pass ) ! { ! out_end = out; ! inp = in; ! in_end = inp + line_size; ! ! if ( y_24pin ) ! { ! for ( ; inp < in_end; inp++, out_end += 24 ) ! { ! gdev_prn_transpose_8x8(inp, line_size, out_end, 3); ! gdev_prn_transpose_8x8(inp + line_size * 8, ! line_size, out_end + 1, 3); ! gdev_prn_transpose_8x8(inp + line_size * 16, ! line_size, out_end + 2, 3); ! } ! /* Remove trailing 0s. */ ! while ( out_end > out && out_end[-1] == 0 && ! out_end[-2] == 0 && out_end[-3] == 0) ! { ! out_end -= 3; ! } ! } ! else ! { ! for ( ; inp < in_end; inp++, out_end += 8 ) ! { ! gdev_prn_transpose_8x8(inp + (ypass * 8*line_size), ! line_size, out_end, 1); ! } ! /* Remove trailing 0s. */ ! while ( out_end > out && out_end[-1] == 0 ) ! { ! out_end--; ! } ! } ! } for ( out_blk = outp = out; outp < out_end; ) ! { ! /* Skip a run of leading 0s. */ ! /* At least 10 are needed to make tabbing */ ! /* worth it. We do everything by 3's to */ ! /* avoid having to make different cases */ ! /* for 9- and 24-pin. */ if ( *outp == 0 && outp + 12 <= out_end && *************** *** 176,216 **** (outp[3] | outp[4] | outp[5]) == 0 && (outp[6] | outp[7] | outp[8]) == 0 && ! (outp[9] | outp[10] | outp[11]) == 0 ! ) ! { byte *zp = outp; int tpos; byte *newp; outp += 12; ! while ( outp + 3 <= out_end && *outp == 0 && ! outp[1] == 0 && outp[2] == 0 ! ) ! outp += 3; tpos = (outp - out) / bytes_per_space; newp = out + tpos * bytes_per_space; if ( newp > zp + 10 ) ! { /* Output preceding bit data. */ ! if ( zp > out_blk ) /* only false at */ ! /* beginning of line */ ! eps_output_run(out_blk, (int)(zp - out_blk), ! y_mult, start_graphics, ! prn_stream, pass); ! /* Tab over to the appropriate position. */ ! fprintf(prn_stream, "\033D%c%c\t", tpos, 0); ! out_blk = outp = newp; ! } ! } ! else ! outp += y_mult; ! } if ( outp > out_blk ) ! eps_output_run(out_blk, (int)(outp - out_blk), ! y_mult, start_graphics, ! prn_stream, pass); fputc('\r', prn_stream); ! } ! skip = 24; ! lnum += 8 * y_mult; ! } /* Eject the page and reinitialize the printer */ --- 263,316 ---- (outp[3] | outp[4] | outp[5]) == 0 && (outp[6] | outp[7] | outp[8]) == 0 && ! (outp[9] | outp[10] | outp[11]) == 0 ) ! { ! byte *zp = outp; int tpos; byte *newp; + outp += 12; ! while ( outp + 3 <= out_end && ! *outp == 0 && ! outp[1] == 0 && outp[2] == 0 ) ! { ! outp += 3; ! } tpos = (outp - out) / bytes_per_space; newp = out + tpos * bytes_per_space; if ( newp > zp + 10 ) ! { ! /* Output preceding bit data.*/ ! if ( zp > out_blk ) ! { ! /* only false at beginning of line */ ! eps_output_run(out_blk, (int)(zp - out_blk), ! out_y_mult, start_graphics, ! prn_stream, pass); ! } ! /* Tab over to the appropriate position. */ ! fprintf(prn_stream, "\033D%c%c\t", tpos, 0); ! out_blk = outp = newp; ! } ! } ! else ! { ! outp += out_y_mult; ! } ! } if ( outp > out_blk ) ! { ! eps_output_run(out_blk, (int)(outp - out_blk), ! out_y_mult, start_graphics, ! prn_stream, pass); ! } fputc('\r', prn_stream); ! } ! if ( ypass < y_passes - 1 ) ! fputs("\033J\001", prn_stream); ! } ! skip = 24 - y_passes + 1; /* no skip on last Y pass */ ! lnum += 8 * in_y_mult; ! } /* Eject the page and reinitialize the printer */ *************** *** 218,223 **** fflush(prn_stream); ! gs_free((char *)out, out_size, 1, "eps_print_page(out)"); ! gs_free((char *)in, in_size, 1, "eps_print_page(in)"); return 0; } --- 318,323 ---- fflush(prn_stream); ! gs_free((char *)buf2, in_size, 1, "eps_print_page(buf2)"); ! gs_free((char *)buf1, in_size, 1, "eps_print_page(buf1)"); return 0; } *************** *** 228,253 **** eps_output_run(byte *data, int count, int y_mult, char start_graphics, FILE *prn_stream, int pass) ! { int xcount = count / y_mult; fputc(033, prn_stream); if ( !(start_graphics & ~3) ) ! { fputc("KLYZ"[start_graphics], prn_stream); ! } else ! { fputc('*', prn_stream); fputc(start_graphics & ~DD, prn_stream); ! } fputc(xcount & 0xff, prn_stream); fputc(xcount >> 8, prn_stream); if ( !pass ) fwrite(data, 1, count, prn_stream); else ! { /* Only write every other column of y_mult bytes. */ int which = pass; ! byte *dp = data; register int i, j; for ( i = 0; i < xcount; i++, which++ ) ! for ( j = 0; j < y_mult; j++, dp++ ) ! { putc(((which & 1) ? *dp : 0), prn_stream); ! } ! } } --- 328,376 ---- eps_output_run(byte *data, int count, int y_mult, char start_graphics, FILE *prn_stream, int pass) ! { ! int xcount = count / y_mult; ! fputc(033, prn_stream); if ( !(start_graphics & ~3) ) ! { ! fputc("KLYZ"[start_graphics], prn_stream); ! } else ! { ! fputc('*', prn_stream); fputc(start_graphics & ~DD, prn_stream); ! } fputc(xcount & 0xff, prn_stream); fputc(xcount >> 8, prn_stream); if ( !pass ) + { fwrite(data, 1, count, prn_stream); + } else ! { ! /* Only write every other column of y_mult bytes. */ int which = pass; ! register byte *dp = data; register int i, j; + for ( i = 0; i < xcount; i++, which++ ) ! { ! for ( j = 0; j < y_mult; j++, dp++ ) ! { ! putc(((which & 1) ? *dp : 0), prn_stream); ! } ! } ! } ! } ! ! private int ! eps_print_page1(gx_device_printer *pdev, FILE *prn_stream) ! { ! return(eps_print_page(pdev, prn_stream, 0)); ! } ! ! private int ! eps_print_page2(gx_device_printer *pdev, FILE *prn_stream) ! { ! return(eps_print_page(pdev, prn_stream, 1)); } diff -rc2N gs241/gdevgif.c gs25/gdevgif.c *** gs241/gdevgif.c Sat Apr 18 14:17:40 1992 --- gs25/gdevgif.c Tue Jul 21 05:38:32 1992 *************** *** 43,46 **** --- 43,47 ---- /* The same print_page routine currently serves for */ /* both monochrome and color. */ + private dev_proc_open_device(gif_open); private dev_proc_print_page(gif_print_page); *************** *** 47,52 **** /* Monochrome. */ gx_device_printer gs_gifmono_device = ! prn_device(prn_std_procs, "gifmono", WIDTH_10THS, HEIGHT_10THS, X_DPI, Y_DPI, --- 48,55 ---- /* Monochrome. */ + private gx_device_procs gifmono_procs = + prn_procs(gif_open, gdev_prn_output_page, gdev_prn_close); gx_device_printer gs_gifmono_device = ! prn_device(gifmono_procs, "gifmono", WIDTH_10THS, HEIGHT_10THS, X_DPI, Y_DPI, *************** *** 58,62 **** private gx_device_procs gif8_procs = ! prn_color_procs(gdev_prn_open, gdev_prn_output_page, gdev_prn_close, pc_8bit_map_rgb_color, pc_8bit_map_color_rgb); gx_device_printer gs_gif8_device = --- 61,65 ---- private gx_device_procs gif8_procs = ! prn_color_procs(gif_open, gdev_prn_output_page, gdev_prn_close, pc_8bit_map_rgb_color, pc_8bit_map_color_rgb); gx_device_printer gs_gif8_device = *************** *** 69,72 **** --- 72,82 ---- /* ------ Private definitions ------ */ + /* All two-byte quantities are stored LSB-first! */ + #if arch_is_big_endian + # define assign_ushort(a,v) a = ((v) >> 8) + ((v) << 8) + #else + # define assign_ushort(a,v) a = (v) + #endif + typedef struct gif_header_s { byte signature[3]; /* magic number == 'GIF' */ *************** *** 163,167 **** if ( pe->table == 0 ) ! return gs_error_VMerror; /* can't allocate buffers */ lzw_reset(pe); --- 173,177 ---- if ( pe->table == 0 ) ! return_error(gs_error_VMerror); /* can't allocate buffers */ lzw_reset(pe); *************** *** 302,307 **** /* Write a page to a file in GIF format. */ ! int gif_print_page(gx_device_printer *pdev, FILE *file) { int raster = gdev_prn_bytes_per_scan_line(pdev); --- 312,332 ---- + /* Open the device. The only reason for this routine is */ + /* to print the obnoxious copyright notice. */ + private int + gif_open(gx_device *pdev) + { int code = gdev_prn_open(pdev); + if ( code < 0 ) return code; + + puts("The Graphics Interchange Format(c) is"); + puts("the Copyright Property of CompuServe Incorporated."); + puts("GIF(sm) is a Service Mark property of CompuServe Incorporated."); + + return 0; + } + + /* Write a page to a file in GIF format. */ ! private int gif_print_page(gx_device_printer *pdev, FILE *file) { int raster = gdev_prn_bytes_per_scan_line(pdev); *************** *** 308,311 **** --- 333,338 ---- int height = pdev->height; int depth = pdev->color_info.depth; + int gif_width = raster * (8 / depth); /* decoders want the width */ + /* on a byte boundary */ byte *row = (byte *)gs_malloc(raster * 2, 1, "gif file buffer"); byte *end = row + raster; *************** *** 317,321 **** if ( row == 0 ) /* can't allocate row buffer */ ! return gs_error_VMerror; code = lzw_init(&encoder, (depth == 1 ? 2 : depth), file); if ( code < 0 ) --- 344,348 ---- if ( row == 0 ) /* can't allocate row buffer */ ! return_error(gs_error_VMerror); code = lzw_init(&encoder, (depth == 1 ? 2 : depth), file); if ( code < 0 ) *************** *** 326,334 **** memcpy(header.signature, "GIF", 3); memcpy(header.version, "87a", 3); ! header.width = raster * (8/depth); /*pdev->width;*/ ! /* for most decoders the */ ! /* width must be on byte */ ! /* boundry */ ! header.height = height; /* header.flags.globalcolor = TRUE; */ /* header.flags.colorres = depth-1; */ --- 353,358 ---- memcpy(header.signature, "GIF", 3); memcpy(header.version, "87a", 3); ! assign_ushort(header.width, gif_width); ! assign_ushort(header.height, height); /* header.flags.globalcolor = TRUE; */ /* header.flags.colorres = depth-1; */ *************** *** 359,364 **** header_desc.left_pos = 0; header_desc.top_pos = 0; ! header_desc.width = raster * (8/depth); /*pdev->width;*/ ! header_desc.height = height; /* header_desc.flags.localcolor = FALSE; */ /* header_desc.flags.interlace = FALSE; */ --- 383,388 ---- header_desc.left_pos = 0; header_desc.top_pos = 0; ! assign_ushort(header_desc.width, gif_width); ! assign_ushort(header_desc.height, height); /* header_desc.flags.localcolor = FALSE; */ /* header_desc.flags.interlace = FALSE; */ *************** *** 375,384 **** goto gif_done; } - - fflush(file); - - printf("The Graphics Interchange Format(c) is \n"); - printf("the Copyright Property of CompuServe Incorporated.\n"); - printf("GIF(sm) is a Service Mark property of CompuServe Incorporated\n"); fputc(encoder.bits, file); /* start with code size */ --- 399,402 ---- diff -rc2N gs241/gdevln03.c gs25/gdevln03.c *** gs241/gdevln03.c Sun Nov 24 12:41:32 1991 --- gs25/gdevln03.c Thu Jun 11 15:49:48 1992 *************** *** 29,32 **** --- 29,33 ---- ported to VMS (contributed by Martin Stiftinger, TU Vienna) lpd 91-11-24 sped up by removing multiplies from inner loop + ijmp 92-04-14 add support for la75/la50 (macphed@dvinci.usask.ca) */ *************** *** 33,36 **** --- 34,40 ---- #include "gdevprn.h" + /* Forward references */ + private int sixel_printpage(P3(gx_device_printer *pdev, FILE *prn_stream, const char *init)); + /* The device descriptor */ private dev_proc_print_page(ln03_print_page); *************** *** 42,45 **** --- 46,111 ---- 0, 0.3, 0, 0, /* margins */ 1, ln03_print_page); + /* switch to graphics mode, 300 dpi + [!p DECSTR soft terminal reset + [11h PUM select unit of measurement + [7 I SSU select pixel as size unit + [?52h DECOPM origin is upper-left corner + [3475t DECSLPP form length (3475 pixels) + [0;2460s DECSLRM left and right margins (0, 2460 pixels) + P0;0;1q select sixel graphics mode + "1;1 DECGRA aspect ratio (1:1) + *** Parameters are for A4 paper format. + *** Could someone please check them for american paper format? */ + #define LN03_INIT \ + "\033[!p\033[11h\033[7 I\033[?52h\033[3475t\033[0;2460s\033P0;0;1q\"1;1" + + private int + ln03_print_page(gx_device_printer *pdev, FILE *prn_stream) + { + return (sixel_printpage(pdev,prn_stream,LN03_INIT)); + } + + /* + * LA75 dot matrix printer device. + * This uses North American 8.5 x 11 inch paper size. + */ + private dev_proc_print_page(la75_print_page); + gx_device_printer gs_la75_device = + prn_device(prn_std_procs, "la75", + 85, + 110, + 144, 72, + 0, 0, 0.5, 0, + 1, la75_print_page); + + #define LA75_INIT "\033P0;0;0q" + + private int + la75_print_page(gx_device_printer *pdev, FILE *prn_stream) + { + return (sixel_printpage(pdev,prn_stream,LA75_INIT)); + } + + /* + * LA50 dot matrix printer device. + * This uses North American 8.5 x 11 inch paper size. + */ + private dev_proc_print_page(la50_print_page); + gx_device_printer gs_la50_device = + prn_device(prn_std_procs, "la50", + 85, + 110, + 144, 72, + 0, 0, 0.5, 0, + 1, la50_print_page); + /* LA50's use a very primitive form of initialization */ + + #define LA50_INIT "\033Pq" + + private int + la50_print_page(gx_device_printer *pdev, FILE *prn_stream) + { + return (sixel_printpage(pdev,prn_stream,LA50_INIT)); + } /* ------ Internal routines ------ */ *************** *** 47,51 **** /* Send the page to the printer. */ private int ! ln03_print_page(gx_device_printer *pdev, FILE *prn_stream) { byte *in, *inp; --- 113,117 ---- /* Send the page to the printer. */ private int ! sixel_printpage(gx_device_printer *pdev, FILE *prn_stream, const char *init) { byte *in, *inp; *************** *** 59,76 **** if (!in) return(-1); ! /* switch to graphics mode, 300 dpi ! [!p DECSTR soft terminal reset ! [11h PUM select unit of measurement ! [7 I SSU select pixel as size unit ! [?52h DECOPM origin is upper-left corner ! [3475t DECSLPP form length (3475 pixels) ! [0;2460s DECSLRM left and right margins (0, 2460 pixels) ! P0;0;1q select sixel graphics mode ! "1;1 DECGRA aspect ratio (1:1) ! *** Parameters are for A4 paper format. ! *** Could someone please check them for american paper format? */ ! fputs( ! "\033[!p\033[11h\033[7 I\033[?52h\033[3475t\033[0;2460s\033P0;0;1q\"1;1", ! prn_stream); /* Print lines of graphics */ --- 125,129 ---- if (!in) return(-1); ! fputs(init,prn_stream); /* Print lines of graphics */ diff -rc2N gs241/gdevmem1.c gs25/gdevmem1.c *** gs241/gdevmem1.c Wed Apr 15 05:18:24 1992 --- gs25/gdevmem1.c Wed Aug 12 18:20:46 1992 *************** *** 38,42 **** /* Return the appropriate memory device for a given */ /* number of bits per pixel (0 if none suitable). */ ! gx_device_memory * gdev_mem_device_for_bits(int bits_per_pixel) { switch ( bits_per_pixel ) --- 38,42 ---- /* Return the appropriate memory device for a given */ /* number of bits per pixel (0 if none suitable). */ ! const gx_device_memory * gdev_mem_device_for_bits(int bits_per_pixel) { switch ( bits_per_pixel ) *************** *** 53,56 **** --- 53,62 ---- } + /* Compute the raster (bytes per scan line). */ + uint + gdev_mem_raster(const gx_device_memory *dev) + { return (((ulong)(dev->width) * dev->color_info.depth + 31) >> 5) << 2; + } + /* Compute the size of the bitmap storage, */ /* including the space for the scan line pointer table. */ *************** *** 57,65 **** /* Note that scan lines are padded to a multiple of 4 bytes. */ ulong ! gdev_mem_bitmap_size(gx_device_memory *dev) ! { unsigned raster = ! ((dev->width * dev->color_info.depth + 31) >> 5) << 2; ! mdev->raster = raster; ! return (ulong)dev->height * (raster + sizeof(byte *)); } --- 63,68 ---- /* Note that scan lines are padded to a multiple of 4 bytes. */ ulong ! gdev_mem_bitmap_size(const gx_device_memory *dev) ! { return (ulong)dev->height * (gdev_mem_raster(dev) + sizeof(byte *)); } *************** *** 68,72 **** mem_open(gx_device *dev) { byte *scan_line = mdev->base; ! uint raster = mdev->raster; byte **pptr = (byte **)(scan_line + (uint)dev->height * raster); byte **pend = pptr + dev->height; --- 71,75 ---- mem_open(gx_device *dev) { byte *scan_line = mdev->base; ! uint raster = mdev->raster = gdev_mem_raster((gx_device_memory *)dev); byte **pptr = (byte **)(scan_line + (uint)dev->height * raster); byte **pend = pptr + dev->height; *************** *** 91,95 **** void mem_get_initial_matrix(gx_device *dev, gs_matrix *pmat) ! { *pmat = mdev->initial_matrix; } --- 94,103 ---- void mem_get_initial_matrix(gx_device *dev, gs_matrix *pmat) ! { pmat->xx = mdev->initial_matrix.xx; ! pmat->xy = mdev->initial_matrix.xy; ! pmat->yx = mdev->initial_matrix.yx; ! pmat->yy = mdev->initial_matrix.yy; ! pmat->tx = mdev->initial_matrix.tx; ! pmat->ty = mdev->initial_matrix.ty; } *************** *** 116,120 **** #if !arch_is_big_endian if ( !dev->bytes_le ) return; /* already in order */ ! memswab(dev->base, dev->base, dev->raster * dev->height); dev->bytes_le = 0; #endif --- 124,128 ---- #if !arch_is_big_endian if ( !dev->bytes_le ) return; /* already in order */ ! memswab2(dev->base, dev->base, dev->raster * dev->height); dev->bytes_le = 0; #endif *************** *** 132,140 **** uint count = min(size / bytes_per_line, dev->height - y); int swap = mdev->bytes_le; - if ( !mdev->raster ) /* compute it now */ - (void)gdev_mem_bitmap_size(mdev); if ( bytes_per_line == mdev->raster ) { if ( swap && pad_to_word >= 0 ) ! memswab(src, dest, bytes_per_line * count); else memcpy(dest, src, bytes_per_line * count); --- 140,146 ---- uint count = min(size / bytes_per_line, dev->height - y); int swap = mdev->bytes_le; if ( bytes_per_line == mdev->raster ) { if ( swap && pad_to_word >= 0 ) ! memswab2(src, dest, bytes_per_line * count); else memcpy(dest, src, bytes_per_line * count); *************** *** 147,151 **** /* bytes_per_line is odd. */ if ( bytes_per_line & 1 ) ! { memswab(src, dest, bytes_per_line - 1); dest[bytes_per_line - 1] = src[bytes_per_line]; --- 153,157 ---- /* bytes_per_line is odd. */ if ( bytes_per_line & 1 ) ! { memswab2(src, dest, bytes_per_line - 1); dest[bytes_per_line - 1] = src[bytes_per_line]; *************** *** 152,156 **** } else ! memswab(src, dest, bytes_per_line); } else --- 158,162 ---- } else ! memswab2(src, dest, bytes_per_line); } else *************** *** 175,179 **** /* The instance is public. */ ! gx_device_memory mem_mono_device = mem_device("image(mono)", 1, mem_mono_procs); --- 181,185 ---- /* The instance is public. */ ! const gx_device_memory mem_mono_device = mem_device("image(mono)", 1, mem_mono_procs); *************** *** 211,218 **** bit = x & chunk_bit_mask; if ( bit + w <= chunk_bits ) ! { /* Only one word. */ right_mask = ! (w == chunk_bits ? chunk_all_bits : chunk_hi_bits(w)) ! >> bit; } else --- 217,229 ---- bit = x & chunk_bit_mask; if ( bit + w <= chunk_bits ) ! { /* ! * Only one word. We have to split following statement ! * because of a bug in the Xenix C compiler (it produces ! * a signed rather than an unsigned shift if we don't ! * split). ! */ right_mask = ! (w == chunk_bits ? chunk_all_bits : chunk_hi_bits(w)); ! right_mask >>= bit; } else *************** *** 272,278 **** copy_or = 0, copy_store, copy_and, copy_funny } copy_function; ! typedef enum { ! copy_right = 0, copy_left = 4 ! } copy_shift; typedef struct { short invert; --- 283,290 ---- copy_or = 0, copy_store, copy_and, copy_funny } copy_function; ! /* copy_right/left is not an enum, because compilers complain about */ ! /* an enumeration clash when these are added to a copy_function. */ ! #define copy_right ((copy_function)0) ! #define copy_left ((copy_function)4) typedef struct { short invert; *************** *** 303,309 **** private int mem_mono_copy_mono(gx_device *dev, ! byte *base, int sourcex, int sraster, gx_bitmap_id id, int x, int y, int w, int h, gx_color_index zero, gx_color_index one) ! { register byte *bptr; /* actually chunk * */ int dbit, wleft; uint mask; --- 315,321 ---- private int mem_mono_copy_mono(gx_device *dev, ! const byte *base, int sourcex, int sraster, gx_bitmap_id id, int x, int y, int w, int h, gx_color_index zero, gx_color_index one) ! { register const byte *bptr; /* actually chunk * */ int dbit, wleft; uint mask; *************** *** 460,464 **** { int ccase = (skew >= 0 ? copy_right : ! ((bptr += chunk_bytes), copy_left)) + function; int cskew = -skew & chunk_bit_mask; skew &= chunk_bit_mask; --- 472,477 ---- { int ccase = (skew >= 0 ? copy_right : ! ((bptr += chunk_bytes), copy_left)) ! + (int)function; int cskew = -skew & chunk_bit_mask; skew &= chunk_bit_mask; diff -rc2N gs241/gdevmem2.c gs25/gdevmem2.c *** gs241/gdevmem2.c Sat Apr 11 08:42:32 1992 --- gs25/gdevmem2.c Thu Apr 30 00:31:54 1992 *************** *** 97,101 **** /* The instance is public. */ ! gx_device_memory mem_mapped8_color_device = mem_device("image(8)", 8, mem_mapped8_procs); --- 97,101 ---- /* The instance is public. */ ! const gx_device_memory mem_mapped8_color_device = mem_device("image(8)", 8, mem_mapped8_procs); *************** *** 121,127 **** private int mem_mapped8_copy_mono(gx_device *dev, ! byte *base, int sourcex, int sraster, gx_bitmap_id id, int x, int y, int w, int h, gx_color_index zero, gx_color_index one) ! { byte *line; int first_bit; declare_scan_ptr(dest); --- 121,127 ---- private int mem_mapped8_copy_mono(gx_device *dev, ! const byte *base, int sourcex, int sraster, gx_bitmap_id id, int x, int y, int w, int h, gx_color_index zero, gx_color_index one) ! { const byte *line; int first_bit; declare_scan_ptr(dest); *************** *** 132,136 **** while ( h-- > 0 ) { register byte *pptr = dest; ! byte *sptr = line; register int sbyte = *sptr; register uint bit = first_bit; --- 132,136 ---- while ( h-- > 0 ) { register byte *pptr = dest; ! const byte *sptr = line; register int sbyte = *sptr; register uint bit = first_bit; *************** *** 179,183 **** private int mem_mapped8_copy_color(gx_device *dev, ! byte *base, int sourcex, int sraster, gx_bitmap_id id, int x, int y, int w, int h) { check_rect(); --- 179,183 ---- private int mem_mapped8_copy_color(gx_device *dev, ! const byte *base, int sourcex, int sraster, gx_bitmap_id id, int x, int y, int w, int h) { check_rect(); *************** *** 199,203 **** /* The instance is public. */ ! gx_device_memory mem_true16_color_device = mem_device("image(16)", 16, mem_true16_procs); --- 199,203 ---- /* The instance is public. */ ! const gx_device_memory mem_true16_color_device = mem_device("image(16)", 16, mem_true16_procs); *************** *** 248,254 **** private int mem_true16_copy_mono(gx_device *dev, ! byte *base, int sourcex, int sraster, gx_bitmap_id id, int x, int y, int w, int h, gx_color_index zero, gx_color_index one) ! { byte *line; int first_bit; declare_scan_ptr(dest); --- 248,254 ---- private int mem_true16_copy_mono(gx_device *dev, ! const byte *base, int sourcex, int sraster, gx_bitmap_id id, int x, int y, int w, int h, gx_color_index zero, gx_color_index one) ! { const byte *line; int first_bit; declare_scan_ptr(dest); *************** *** 259,263 **** while ( h-- > 0 ) { register ushort *pptr = (ushort *)dest; ! byte *sptr = line; register int sbyte = *sptr++; register int bit = first_bit; --- 259,263 ---- while ( h-- > 0 ) { register ushort *pptr = (ushort *)dest; ! const byte *sptr = line; register int sbyte = *sptr++; register int bit = first_bit; *************** *** 286,290 **** private int mem_true16_copy_color(gx_device *dev, ! byte *base, int sourcex, int sraster, gx_bitmap_id id, int x, int y, int w, int h) { check_rect(); --- 286,290 ---- private int mem_true16_copy_color(gx_device *dev, ! const byte *base, int sourcex, int sraster, gx_bitmap_id id, int x, int y, int w, int h) { check_rect(); *************** *** 337,341 **** mem_true_procs(mem_true24_copy_mono, mem_true24_copy_color, mem_true24_fill_rectangle); ! gx_device_memory mem_true24_color_device = mem_device("image(24)", 24, mem_true24_procs); --- 337,341 ---- mem_true_procs(mem_true24_copy_mono, mem_true24_copy_color, mem_true24_fill_rectangle); ! const gx_device_memory mem_true24_color_device = mem_device("image(24)", 24, mem_true24_procs); *************** *** 372,378 **** private int mem_true24_copy_mono(gx_device *dev, ! byte *base, int sourcex, int sraster, gx_bitmap_id id, int x, int y, int w, int h, gx_color_index zero, gx_color_index one) ! { byte *line; int first_bit; declare_unpack_color(r0, g0, b0, zero); --- 372,378 ---- private int mem_true24_copy_mono(gx_device *dev, ! const byte *base, int sourcex, int sraster, gx_bitmap_id id, int x, int y, int w, int h, gx_color_index zero, gx_color_index one) ! { const byte *line; int first_bit; declare_unpack_color(r0, g0, b0, zero); *************** *** 385,389 **** while ( h-- > 0 ) { register byte *pptr = dest; ! byte *sptr = line; register int sbyte = *sptr++; register int bit = first_bit; --- 385,389 ---- while ( h-- > 0 ) { register byte *pptr = dest; ! const byte *sptr = line; register int sbyte = *sptr++; register int bit = first_bit; *************** *** 412,416 **** private int mem_true24_copy_color(gx_device *dev, ! byte *base, int sourcex, int sraster, gx_bitmap_id id, int x, int y, int w, int h) { check_rect(); --- 412,416 ---- private int mem_true24_copy_color(gx_device *dev, ! const byte *base, int sourcex, int sraster, gx_bitmap_id id, int x, int y, int w, int h) { check_rect(); *************** *** 428,432 **** mem_true_procs(mem_true32_copy_mono, mem_true32_copy_color, mem_true32_fill_rectangle); ! gx_device_memory mem_true32_color_device = mem_device("image(32)", 32, mem_true32_procs); --- 428,432 ---- mem_true_procs(mem_true32_copy_mono, mem_true32_copy_color, mem_true32_fill_rectangle); ! const gx_device_memory mem_true32_color_device = mem_device("image(32)", 32, mem_true32_procs); *************** *** 464,472 **** private int mem_true32_copy_mono(gx_device *dev, ! byte *base, int sourcex, int sraster, gx_bitmap_id id, int x, int y, int w, int h, gx_color_index zero, gx_color_index one) { gx_color_index a_zero = arrange_bytes(zero); gx_color_index a_one = arrange_bytes(one); ! byte *line; int first_bit; declare_scan_ptr(dest); --- 464,472 ---- private int mem_true32_copy_mono(gx_device *dev, ! const byte *base, int sourcex, int sraster, gx_bitmap_id id, int x, int y, int w, int h, gx_color_index zero, gx_color_index one) { gx_color_index a_zero = arrange_bytes(zero); gx_color_index a_one = arrange_bytes(one); ! const byte *line; int first_bit; declare_scan_ptr(dest); *************** *** 477,481 **** while ( h-- > 0 ) { register gx_color_index *pptr = (gx_color_index *)dest; ! byte *sptr = line; register int sbyte = *sptr++; register int bit = first_bit; --- 477,481 ---- while ( h-- > 0 ) { register gx_color_index *pptr = (gx_color_index *)dest; ! const byte *sptr = line; register int sbyte = *sptr++; register int bit = first_bit; *************** *** 504,508 **** private int mem_true32_copy_color(gx_device *dev, ! byte *base, int sourcex, int sraster, gx_bitmap_id id, int x, int y, int w, int h) { check_rect(); --- 504,508 ---- private int mem_true32_copy_color(gx_device *dev, ! const byte *base, int sourcex, int sraster, gx_bitmap_id id, int x, int y, int w, int h) { check_rect(); diff -rc2N gs241/gdevmem3.c gs25/gdevmem3.c *** gs241/gdevmem3.c Sat Mar 28 05:42:48 1992 --- gs25/gdevmem3.c Sat May 2 16:21:18 1992 *************** *** 35,42 **** #define chunk byte - /* Import the monobit device from gdevmem1 */ - /* so we can use its procedures. */ - extern gx_device_memory mem_mono_device; - /* Import the color mapping procedures from gdevmem2. */ extern dev_proc_map_rgb_color(mem_mapped_map_rgb_color); --- 35,38 ---- *************** *** 69,73 **** /* The instance is public. */ ! gx_device_memory mem_mapped2_color_device = mem_device("image(2)", 2, mem_mapped2_procs); --- 65,69 ---- /* The instance is public. */ ! const gx_device_memory mem_mapped2_color_device = mem_device("image(2)", 2, mem_mapped2_procs); *************** *** 105,111 **** private int mem_mapped2_copy_mono(gx_device *dev, ! byte *base, int sourcex, int sraster, gx_bitmap_id id, int x, int y, int w, int h, gx_color_index zero, gx_color_index one) ! { byte *line; int first_bit; byte first_mask, b0, b1; --- 101,107 ---- private int mem_mapped2_copy_mono(gx_device *dev, ! const byte *base, int sourcex, int sraster, gx_bitmap_id id, int x, int y, int w, int h, gx_color_index zero, gx_color_index one) ! { const byte *line; int first_bit; byte first_mask, b0, b1; *************** *** 122,126 **** while ( h-- > 0 ) { register byte *pptr = (byte *)dest; ! byte *sptr = line; register int sbyte = *sptr++; register int bit = first_bit; --- 118,122 ---- while ( h-- > 0 ) { register byte *pptr = (byte *)dest; ! const byte *sptr = line; register int sbyte = *sptr++; register int bit = first_bit; *************** *** 151,155 **** private int mem_mapped2_copy_color(gx_device *dev, ! byte *base, int sourcex, int sraster, gx_bitmap_id id, int x, int y, int w, int h) { int code; --- 147,151 ---- private int mem_mapped2_copy_color(gx_device *dev, ! const byte *base, int sourcex, int sraster, gx_bitmap_id id, int x, int y, int w, int h) { int code; *************** *** 177,181 **** /* The instance is public. */ ! gx_device_memory mem_mapped4_color_device = mem_device("image(4)", 4, mem_mapped4_procs); --- 173,177 ---- /* The instance is public. */ ! const gx_device_memory mem_mapped4_color_device = mem_device("image(4)", 4, mem_mapped4_procs); *************** *** 215,221 **** private int mem_mapped4_copy_mono(gx_device *dev, ! byte *base, int sourcex, int sraster, gx_bitmap_id id, int x, int y, int w, int h, gx_color_index zero, gx_color_index one) ! { byte *line; int first_bit; byte first_mask, b0, b1; --- 211,217 ---- private int mem_mapped4_copy_mono(gx_device *dev, ! const byte *base, int sourcex, int sraster, gx_bitmap_id id, int x, int y, int w, int h, gx_color_index zero, gx_color_index one) ! { const byte *line; int first_bit; byte first_mask, b0, b1; *************** *** 230,234 **** while ( h-- > 0 ) { register byte *pptr = (byte *)dest; ! byte *sptr = line; register int sbyte = *sptr++; register int bit = first_bit; --- 226,230 ---- while ( h-- > 0 ) { register byte *pptr = (byte *)dest; ! const byte *sptr = line; register int sbyte = *sptr++; register int bit = first_bit; *************** *** 259,263 **** private int mem_mapped4_copy_color(gx_device *dev, ! byte *base, int sourcex, int sraster, gx_bitmap_id id, int x, int y, int w, int h) { int code; --- 255,259 ---- private int mem_mapped4_copy_color(gx_device *dev, ! const byte *base, int sourcex, int sraster, gx_bitmap_id id, int x, int y, int w, int h) { int code; diff -rc2N gs241/gdevmswn.c gs25/gdevmswn.c *** gs241/gdevmswn.c --- gs25/gdevmswn.c Sat Aug 15 04:28:50 1992 *************** *** 0 **** --- 1,996 ---- + /* Copyright (C) 1989, 1992 Aladdin Enterprises. All rights reserved. + Distributed by Free Software Foundation, Inc. + + This file is part of Ghostscript. + + Ghostscript is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY. No author or distributor accepts responsibility + to anyone for the consequences of using it or for whether it serves any + particular purpose or works at all, unless he says so in writing. Refer + to the Ghostscript General Public License for full details. + + Everyone is granted permission to copy, modify and redistribute + Ghostscript, but only under the conditions described in the Ghostscript + General Public License. A copy of this license is supposed to have been + given to you along with Ghostscript so you can know your rights and + responsibilities. It should be in a file named COPYING. Among other + things, the copyright notice and this notice must be preserved on all + copies. */ + + /* gdevmswn.c */ + /* + * Microsoft Windows 3.n driver for Ghostscript. + * Original version by Russell Lang and Maurice Castro with help from + * Programming Windows, 2nd Ed., Charles Petzold, Microsoft Press; + * created from gdevbgi.c and gnuplot/term/win.trm 5th June 1992. + * Extensively modified by L. Peter Deutsch, Aladdin Enterprises. + */ + #include + #include + #include + #include "gx.h" + #include "gserrors.h" + #include "gxdevice.h" + #include "gp.h" + #include "gpcheck.h" + + /* system menu constants for image window */ + #define M_COPY_CLIP 1 + + /* externals from gp_win.c */ + extern HWND FAR hwndeasy; + extern HANDLE FAR phInstance; + extern const char FAR szAppName[]; + extern gx_device *gdev_win_open_list; + + typedef struct gx_device_win_s gx_device_win; + + /* Forward references */ + private LPLOGPALETTE win_makepalette(P1(gx_device_win *)); + private void win_makeimg(P1(gx_device_win *)); + private void win_addtool(P2(gx_device_win *, int)); + private void win_maketools(P2(gx_device_win *, HDC)); + private void win_destroytools(P1(gx_device_win *)); + private void win_nomemory(); + private void win_update(P2(gx_device_win *, int)); + private const char FAR imgname[] = "Ghostscript Image"; + + /* See gxdevice.h for the definitions of the procedures. */ + + private dev_proc_open_device(win_open); + private dev_proc_sync_output(win_sync_output); + private dev_proc_output_page(win_output_page); + private dev_proc_close_device(win_close); + private dev_proc_map_rgb_color(win_map_rgb_color); + private dev_proc_map_color_rgb(win_map_color_rgb); + private dev_proc_fill_rectangle(win_fill_rectangle); + private dev_proc_tile_rectangle(win_tile_rectangle); + private dev_proc_copy_mono(win_copy_mono); + private dev_proc_copy_color(win_copy_color); + private dev_proc_draw_line(win_draw_line); + + /* The device descriptor */ + struct gx_device_win_s { + gx_device_common; + int nColors; + + /* Handles */ + + HWND FAR hwndimg; + HBITMAP FAR hbitmap; + HDC FAR hdcbit; + HPEN hpen, *hpens; + HBRUSH hbrush, *hbrushs; + HPALETTE hpalette, himgpalette; + LPLOGPALETTE lpalette, limgpalette; + + /* A staging bitmap for copy_mono. */ + /* We want one big enough to handle the standard 16x16 halftone; */ + /* this is also big enough for ordinary-size characters. */ + + #define bmWidthBytes 4 /* must be even */ + #define bmWidthBits (bmWidthBytes * 8) + #define bmHeight 16 + HBITMAP FAR hbmmono; + HDC FAR hdcmono; + #define rop_write_at_1s 0xE20746L /* write brush at 1's */ + #define rop_write_at_0s 0xB8074AL /* write brush at 0's */ + gx_bitmap_id bm_id; + + /* Window scrolling stuff */ + + int cxClient, cyClient; + int cxAdjust, cyAdjust; + int nVscrollPos, nVscrollMax; + int nHscrollPos, nHscrollMax; + + /* Link for the list of open Windows devices */ + + gx_device_win *next_wdev; + }; + #define wdev ((gx_device_win *)dev) + static gx_device_procs win_procs = { + win_open, + gx_default_get_initial_matrix, + win_sync_output, + win_output_page, + win_close, + win_map_rgb_color, + win_map_color_rgb, + win_fill_rectangle, + win_tile_rectangle, + win_copy_mono, + win_copy_color, + win_draw_line, + gx_default_get_bits, + gx_default_get_props, + gx_default_put_props + }; + gx_device_win gs_mswin_device = { + sizeof(gx_device_win), + &win_procs, + "win", + 32767, 32767, /* win_open() fills these in later */ + 96.0, 96.0, /* win_open() fills these in later */ + no_margins, + dci_black_and_white, + 0, /* not open yet */ + 2 /* nColors = 2 */ + }; + + /* Open the win driver */ + private int + win_open(gx_device *dev) + { HDC hdc; + int i; + + win_makeimg(wdev); + ShowWindow(wdev->hwndimg, SW_SHOWMINIMIZED); + BringWindowToTop(hwndeasy); + + hdc = GetDC(wdev->hwndimg); + + /* Set parameters that were unknown before opening device */ + if (dev->width == 32767) + dev->width = (int)(8.5 * dev->x_pixels_per_inch); + if (dev->height == 32767) + dev->height = (int)(11.0 * dev->y_pixels_per_inch); + + /* Find out if the device supports color */ + /* We recognize 2, 16 or 256 color devices */ + wdev->nColors = 1 << (GetDeviceCaps(hdc,PLANES) * GetDeviceCaps(hdc,BITSPIXEL)); + if ( wdev->nColors >= 256 ) { /* use 64 static colors and 166 dynamic colors from 8 planes */ + static const gx_device_color_info win_256color = dci_color(8,31,4); + dev->color_info = win_256color; + wdev->nColors = 64; + } + else if ( wdev->nColors >= 16 ) { + static const gx_device_color_info win_16color = dci_color(4, 2, 3); + dev->color_info = win_16color; + wdev->nColors = 16; + } + else { /* default is black_and_white */ + wdev->nColors = 2; + } + + wdev->hbitmap = CreateCompatibleBitmap(hdc,dev->width,dev->height); + for (i=0; (wdev->hbitmap==(HBITMAP)NULL) && (i<4); i++) { + fprintf(stderr,"\nNot enough memory for bitmap. Halving resolution... "); + dev->x_pixels_per_inch = dev->x_pixels_per_inch/2; + dev->y_pixels_per_inch = dev->y_pixels_per_inch/2; + dev->width = dev->width/2; + dev->height = dev->height/2; + wdev->hbitmap = CreateCompatibleBitmap(hdc,dev->width,dev->height); + } + if (wdev->hbitmap==(HBITMAP)NULL) { + ReleaseDC(wdev->hwndimg, hdc); + win_nomemory(); + } + + /* Create the bitmap and DC for copy_mono. */ + wdev->hbmmono = CreateBitmap(bmWidthBits, bmHeight, 1, 1, NULL); + wdev->hdcmono = CreateCompatibleDC(hdc); + if ( wdev->hbmmono == NULL || wdev->hdcmono == NULL ) + { DeleteObject(wdev->hbitmap); + ReleaseDC(wdev->hwndimg, hdc); + win_nomemory(); + } + SetMapMode(wdev->hdcmono, GetMapMode(hdc)); + SelectObject(wdev->hdcmono, wdev->hbmmono); + wdev->bm_id = gx_no_bitmap_id; + + wdev->hdcbit = CreateCompatibleDC(hdc); /* create Device Context for drawing */ + SelectObject(wdev->hdcbit,wdev->hbitmap); + ReleaseDC(wdev->hwndimg, hdc); + + /* create palette and tools for bitmap */ + if ((wdev->lpalette = win_makepalette(wdev)) + == (LPLOGPALETTE)NULL) + win_nomemory(); + wdev->hpalette = CreatePalette(wdev->lpalette); + (void) SelectPalette(wdev->hdcbit,wdev->hpalette,NULL); + RealizePalette(wdev->hdcbit); + win_maketools(wdev,wdev->hdcbit); + + /* create palette for display */ + if ((wdev->limgpalette = win_makepalette(wdev)) + == (LPLOGPALETTE)NULL) + win_nomemory(); + wdev->himgpalette = CreatePalette(wdev->limgpalette); + + /* Initialize the scrolling information. */ + + wdev->cxClient = wdev->cyClient = 0; + wdev->nVscrollPos = wdev->nVscrollMax = 0; + wdev->nHscrollPos = wdev->nHscrollMax = 0; + + /* Link this device onto the list */ + wdev->next_wdev = (gx_device_win *)gdev_win_open_list; + gdev_win_open_list = dev; + + return 0; + } + + /* Make the output appear on the screen. */ + private int + win_sync_output(gx_device *dev) + { + RECT rect; + if ( !IsWindow(wdev->hwndimg) ) { /* some clod closed the window */ + win_makeimg(wdev); + ShowWindow(wdev->hwndimg, SW_SHOWMINIMIZED); + } + if ( !IsIconic(wdev->hwndimg) ) { /* redraw window */ + GetClientRect(wdev->hwndimg, &rect); + InvalidateRect(wdev->hwndimg, (LPRECT) &rect, 1); + UpdateWindow(wdev->hwndimg); + } + return(0); + } + + /* Make the window visible, and display the output. */ + private int + win_output_page(gx_device *dev, int copies, int flush) + { + if (IsIconic(wdev->hwndimg)) /* useless as an Icon so fix it */ + ShowWindow(wdev->hwndimg, SW_SHOWNORMAL); + + BringWindowToTop(wdev->hwndimg); + return( win_sync_output(dev) ); + } + + /* Close the win driver */ + private int + win_close(gx_device *dev) + { + /* Free resources */ + + win_destroytools(wdev); + DeleteDC(wdev->hdcbit); + DeleteDC(wdev->hdcmono); + DeleteObject(wdev->hbitmap); + DeleteObject(wdev->hpalette); + DeleteObject(wdev->himgpalette); + DeleteObject(wdev->hbmmono); + free(wdev->lpalette); + free(wdev->limgpalette); + DestroyWindow(wdev->hwndimg); + gp_check_interrupts(); /* process WIN_DESTROY message */ + + /* Unlink from list. We do this last so that the WndProc */ + /* can process the destroy message. */ + + { gx_device_win **pwd = (gx_device_win **)&gdev_win_open_list; + while ( *pwd != 0 && *pwd != wdev ) + pwd = &(*pwd)->next_wdev; + if ( pwd != 0 ) /* == 0 should never happen! */ + *pwd = (*pwd)->next_wdev; + } + + return(0); + } + + /* Map a r-g-b color to the colors available under Windows */ + #define win_map32(z)\ + ((((z) >> (gx_color_value_bits - 5)) << 3) +\ + ((z) >> (gx_color_value_bits - 3))) + private gx_color_index + win_map_rgb_color(gx_device *dev, gx_color_value r, gx_color_value g, + gx_color_value b) + { + switch(dev->color_info.depth) { + case 8: { + int i; + LPLOGPALETTE lpal = wdev->lpalette; + PALETTEENTRY *pep; + byte cr, cg, cb; + + /* map colors to 0->255 in 32 steps */ + cr = win_map32(r); + cg = win_map32(g); + cb = win_map32(b); + + /* search in palette */ + for ( i = 0, pep = &lpal->palPalEntry[i]; + i < wdev->nColors; i++, pep++ + ) + { if ((cr == pep->peRed) && + (cg == pep->peGreen) && + (cb == pep->peBlue)) + return((gx_color_index)i); /* found it */ + } + + /* next try adding it to palette */ + if (i < 220) { /* allow 36 for windows and other apps */ + LPLOGPALETTE lipal = wdev->limgpalette; + wdev->nColors = i+1; + DeleteObject(wdev->hpalette); + lpal->palPalEntry[i].peFlags = NULL; + lpal->palPalEntry[i].peRed = cr; + lpal->palPalEntry[i].peGreen = cg; + lpal->palPalEntry[i].peBlue = cb; + lpal->palNumEntries = wdev->nColors; + wdev->hpalette = CreatePalette(lpal); + (void) SelectPalette(wdev->hdcbit,wdev->hpalette,NULL); + RealizePalette(wdev->hdcbit); + win_addtool(wdev, i); + + DeleteObject(wdev->himgpalette); + lipal->palPalEntry[i].peFlags = NULL; + lipal->palPalEntry[i].peRed = cr; + lipal->palPalEntry[i].peGreen = cg; + lipal->palPalEntry[i].peBlue = cb; + lipal->palNumEntries = wdev->nColors; + wdev->himgpalette = CreatePalette(lipal); + + return((gx_color_index)i); /* return new palette index */ + } + + return(-1); /* not found - dither instead */ + } + case 4: { + int color = ((r > gx_max_color_value / 4 ? 4 : 0) + + (g > gx_max_color_value / 4 ? 2 : 0) + + (b > gx_max_color_value / 4 ? 1 : 0) + + (r > gx_max_color_value / 4 * 3 || + g > gx_max_color_value / 4 * 3 ? 8 : 0)); + return((gx_color_index)color); + } + } + return (gx_default_map_rgb_color(dev,r,g,b)); + } + + /* Map a color code to r-g-b. */ + private int + win_map_color_rgb(gx_device *dev, gx_color_index color, + gx_color_value prgb[3]) + { + gx_color_value one; + switch(dev->color_info.depth) { + case 8: + one = (gx_color_value) (gx_max_color_value / 255); + prgb[0] = wdev->lpalette->palPalEntry[(int)color].peRed * one; + prgb[1] = wdev->lpalette->palPalEntry[(int)color].peGreen * one; + prgb[2] = wdev->lpalette->palPalEntry[(int)color].peBlue * one; + break; + case 4: + one = ((int)color & 8 ? gx_max_color_value : gx_max_color_value / 2); + prgb[0] = ((int)color & 4 ? one : 0); + prgb[1] = ((int)color & 2 ? one : 0); + prgb[2] = ((int)color & 1 ? one : 0); + break; + default: + prgb[0] = prgb[1] = prgb[2] = + (int)color ? gx_max_color_value : 0; + } + return 0; + } + + + /* Macro for filling a rectangle with a color. */ + /* Note that it starts with a declaration. */ + #define fill_rect(x, y, w, h, color)\ + RECT rect;\ + rect.left = x, rect.top = y;\ + rect.right = x + w, rect.bottom = y + h;\ + FillRect(wdev->hdcbit, &rect, wdev->hbrushs[(int)color]) + + + /* Fill a rectangle. */ + private int + win_fill_rectangle(gx_device *dev, int x, int y, int w, int h, + gx_color_index color) + { + if ( w > 0 && h > 0 ) + { fill_rect(x, y, w, h, color); + win_update(wdev, h); + } + + return 0; + } + + /* Tile a rectangle. If neither color is transparent, */ + /* pre-clear the rectangle to color0 and just tile with color1. */ + /* This is faster because of how win_copy_mono is implemented. */ + /* Note that this also does the right thing for colored tiles. */ + private int + win_tile_rectangle(gx_device *dev, const gx_bitmap *tile, + int x, int y, int w, int h, gx_color_index czero, gx_color_index cone, + int px, int py) + { if ( w <= 0 || h <= 0 ) return 0; + if ( czero != gx_no_color_index && cone != gx_no_color_index ) + { fill_rect(x, y, w, h, czero); + czero = gx_no_color_index; + } + if ( tile->raster == bmWidthBytes && tile->size.y <= bmHeight && + (px | py) == 0 && cone != gx_no_color_index + ) + { /* We can do this much more efficiently */ + /* by using the internal algorithms of copy_mono */ + /* and gx_default_tile_rectangle. */ + int width = tile->size.x; + int height = tile->size.y; + int rwidth = tile->rep_width; + int irx = ((rwidth & (rwidth - 1)) == 0 ? /* power of 2 */ + x & (rwidth - 1) : + x % rwidth); + int ry = y % tile->rep_height; + int icw = width - irx; + int ch = height - ry; + int ex = x + w, ey = y + h; + int fex = ex - width, fey = ey - height; + int cx, cy; + + if (wdev->hbrush != wdev->hbrushs[(int)cone]) + { wdev->hbrush = wdev->hbrushs[(int)cone]; + SelectObject(wdev->hdcbit,wdev->hbrush); + } + + if ( tile->id != wdev->bm_id || tile->id == gx_no_bitmap_id ) + { wdev->bm_id = tile->id; + SetBitmapBits(wdev->hbmmono, + (DWORD)(bmWidthBytes * tile->size.y), + (BYTE *)tile->data); + } + + #define copy_tile(srcx, srcy, tx, ty, tw, th)\ + BitBlt(wdev->hdcbit, tx, ty, tw, th, wdev->hdcmono, srcx, srcy, rop_write_at_1s) + + if ( ch > h ) ch = h; + for ( cy = y; ; ) + { if ( w <= icw ) + copy_tile(irx, ry, x, cy, w, ch); + else + { copy_tile(irx, ry, x, cy, icw, ch); + cx = x + icw; + while ( cx <= fex ) + { copy_tile(0, ry, cx, cy, width, ch); + cx += width; + } + if ( cx < ex ) + { copy_tile(0, ry, cx, cy, ex - cx, ch); + } + } + if ( (cy += ch) >= ey ) break; + ch = (cy > fey ? ey - cy : height); + ry = 0; + } + + win_update(wdev, h); + return 0; + } + return gx_default_tile_rectangle(dev, tile, x, y, w, h, czero, cone, px, py); + } + + + /* Draw a line */ + private int + win_draw_line(gx_device *dev, int x0, int y0, int x1, int y1, + gx_color_index color) + { + if (wdev->hpen != wdev->hpens[(int)color]) { + wdev->hpen = wdev->hpens[(int)color]; + SelectObject(wdev->hdcbit,wdev->hpen); + } + MoveTo(wdev->hdcbit, x0, y0); + LineTo(wdev->hdcbit, x1, y1); + return 0; + } + + /* Copy a monochrome bitmap. The colors are given explicitly. */ + /* Color = gx_no_color_index means transparent (no effect on the image). */ + private int + win_copy_mono(gx_device *dev, + const byte *base, int sourcex, int raster, gx_bitmap_id id, + int x, int y, int w, int h, + gx_color_index zero, gx_color_index one) + { const byte *ptr_line; + int width_bytes, height; + DWORD rop = rop_write_at_1s; + int color; + BYTE aBit[bmWidthBytes * bmHeight]; + BYTE *aptr = aBit; + + if ( sourcex & ~7 ) + { base += sourcex >> 3; + sourcex &= 7; + } + + /* Break up large transfers into smaller ones. */ + while ( sourcex + w > bmWidthBits ) + { int code = win_copy_mono(dev, base, sourcex + w - bmWidthBits, + raster, gx_no_bitmap_id, + x + w - bmWidthBits, y, + bmWidthBits, h, zero, one); + if ( code < 0 ) return code; + w -= bmWidthBits; + } + while ( h > bmHeight ) + { int code = win_copy_mono(dev, base + (h - bmHeight) * raster, + sourcex, raster, gx_no_bitmap_id, + x, y + h - bmHeight, + w, bmHeight, zero, one); + if ( code < 0 ) return code; + h -= bmHeight; + } + + if ( w <= 0 || h <= 0 ) return 0; + width_bytes = (sourcex + w + 7) >> 3; + ptr_line = base; + + if ( zero == gx_no_color_index ) + { if ( one == gx_no_color_index ) return 0; + color = (int)one; + } + else + { if ( one == gx_no_color_index ) + { color = (int)zero; + rop = rop_write_at_0s; + } + else + { /* Pre-clear the rectangle to zero */ + fill_rect(x, y, w, h, zero); + color = (int)one; + } + } + + if (wdev->hbrush != wdev->hbrushs[(int)color]) + { wdev->hbrush = wdev->hbrushs[(int)color]; + SelectObject(wdev->hdcbit,wdev->hbrush); + } + + if ( id != wdev->bm_id || id == gx_no_bitmap_id ) + { wdev->bm_id = id; + if ( raster == bmWidthBytes ) + { /* We can do the whole thing in a single transfer! */ + SetBitmapBits(wdev->hbmmono, + (DWORD)(bmWidthBytes * h), + (BYTE *)base); + } + else + { for ( height = h; height--; + ptr_line += raster, aptr += bmWidthBytes + ) + { /* Pack the bits into the bitmap. */ + switch ( width_bytes ) + { + default: memcpy(aptr, ptr_line, width_bytes); break; + case 4: aptr[3] = ptr_line[3]; + case 3: aptr[2] = ptr_line[2]; + case 2: aptr[1] = ptr_line[1]; + case 1: aptr[0] = ptr_line[0]; + } + } + SetBitmapBits(wdev->hbmmono, + (DWORD)(bmWidthBytes * h), + &aBit[0]); + } + } + + BitBlt(wdev->hdcbit, x, y, w, h, wdev->hdcmono, sourcex, 0, rop); + win_update(wdev, h); /* message handler */ + return 0; + } + + + /* Copy a color pixel map. This is just like a bitmap, except that */ + /* each pixel takes 8 or 4 bits instead of 1 when device driver has color. */ + private int + win_copy_color(gx_device *dev, + const byte *base, int sourcex, int raster, gx_bitmap_id id, + int x, int y, int w, int h) + { if ( gx_device_has_color(dev) ) + { + switch(dev->color_info.depth) { + case 8: + { int xi, yi; + int skip = raster - w; + const byte *sptr = base + sourcex; + if ( w <= 0 ) return 0; + if ( x < 0 || x + w > dev->width ) + return_error(gs_error_rangecheck); + for ( yi = y; yi - y < h; yi++ ) + { + for ( xi = x; xi - x < w; xi++ ) + { int color = *sptr++; + SetPixel(wdev->hdcbit,xi,yi,PALETTEINDEX(color)); + } + sptr += skip; + } + } + break; + case 4: + { /* color device, four bits per pixel */ + const byte *line = base + (sourcex >> 1); + int dest_y = y, end_x = x + w; + + if ( w <= 0 ) return 0; + while ( h-- ) /* for each line */ + { const byte *source = line; + register int dest_x = x; + if ( sourcex & 1 ) /* odd nibble first */ + { int color = *source++ & 0xf; + SetPixel(wdev->hdcbit,dest_x,dest_y,PALETTEINDEX(color)); + dest_x++; + } + /* Now do full bytes */ + while ( dest_x < end_x ) + { int color = *source >> 4; + SetPixel(wdev->hdcbit,dest_x,dest_y,PALETTEINDEX(color)); + dest_x++; + if ( dest_x < end_x ) + { color = *source++ & 0xf; + SetPixel(wdev->hdcbit,dest_x,dest_y,PALETTEINDEX(color)); + dest_x++; + } + } + dest_y++; + line += raster; + } + } + break; + default: + return(-1); /* panic */ + } + } + else + /* monochrome device: one bit per pixel */ + { /* bitmap is the same as win_copy_mono: one bit per pixel */ + win_copy_mono(dev, base, sourcex, raster, id, x, y, w, h, + (gx_color_index)0, + (gx_color_index)(dev->color_info.depth==8 ? 63 : dev->color_info.max_gray)); + } + win_update(wdev, h); /* message handler */ + return 0; + } + + /* ------ Internal routines ------ */ + + #undef wdev + + /* make image window */ + private void + win_makeimg(gx_device_win *wdev) + { HMENU sysmenu; + wdev->hwndimg = CreateWindow(szAppName, (LPSTR)imgname, + WS_OVERLAPPEDWINDOW | WS_VSCROLL | WS_HSCROLL, + CW_USEDEFAULT, CW_USEDEFAULT, + CW_USEDEFAULT, CW_USEDEFAULT, + NULL, NULL, phInstance, (LPSTR)NULL); + /* modify the menu to have the new items we want */ + sysmenu = GetSystemMenu(wdev->hwndimg,0); /* get the sysmenu */ + AppendMenu(sysmenu, MF_SEPARATOR, 0, NULL); + AppendMenu(sysmenu, MF_STRING, M_COPY_CLIP, "Copy to Clip&board"); + } + + + /* out of memory error exit with message box */ + private void + win_nomemory() + { + MessageBox(hwndeasy,(LPSTR)"Not enough memory",(LPSTR) szAppName, MB_ICONSTOP); + gs_exit(1); + } + + + private LPLOGPALETTE + win_makepalette(gx_device_win *wdev) + { int i, val; + LPLOGPALETTE logpalette; + logpalette = (LPLOGPALETTE) malloc( sizeof(LOGPALETTE) + + (1<<(wdev->color_info.depth)) * sizeof(PALETTEENTRY) ); + if (logpalette == (LPLOGPALETTE)NULL) + return(0); + logpalette->palVersion = 0x300; + logpalette->palNumEntries = wdev->nColors; + for (i=0; inColors; i++) { + logpalette->palPalEntry[i].peFlags = NULL; + switch (wdev->nColors) { + case 64: + /* colors are rrggbb */ + logpalette->palPalEntry[i].peRed = + win_map32(((i & 0x30)>>4)*(gx_max_color_value/3)); + logpalette->palPalEntry[i].peGreen = + win_map32(((i & 0xC)>>2)*(gx_max_color_value/3)); + logpalette->palPalEntry[i].peBlue = + win_map32((i & 3)*(gx_max_color_value/3)); + break; + case 16: + /* colors are irgb */ + val = (i & 8 ? 255 : 255 / 2); + logpalette->palPalEntry[i].peRed = i & 4 ? val : 0; + logpalette->palPalEntry[i].peGreen = i & 2 ? val : 0; + logpalette->palPalEntry[i].peBlue = i & 1 ? val : 0; + break; + case 2: + logpalette->palPalEntry[i].peRed = + logpalette->palPalEntry[i].peGreen = + logpalette->palPalEntry[i].peBlue = (i ? 255 : 0); + break; + } + } + return(logpalette); + } + + + private void + win_addtool(gx_device_win *wdev, int i) + { + wdev->hpens[i] = CreatePen(PS_SOLID, 1, PALETTEINDEX(i)); + wdev->hbrushs[i] = CreateSolidBrush(PALETTEINDEX(i)); + } + + + private void + win_maketools(gx_device_win *wdev, HDC hdc) + { int i; + wdev->hpens = malloc( (1<<(wdev->color_info.depth)) * sizeof(HPEN) ); + wdev->hbrushs = malloc( (1<<(wdev->color_info.depth)) * sizeof(HBRUSH) ); + if (wdev->hpens && wdev->hbrushs) { + for (i=0; inColors; i++) + win_addtool(wdev, i); + + wdev->hpen = wdev->hpens[0]; + SelectObject(hdc,wdev->hpen); + + wdev->hbrush = wdev->hbrushs[0]; + SelectObject(hdc,wdev->hbrush); + } + } + + + private void + win_destroytools(gx_device_win *wdev) + { int i; + for (i=0; inColors; i++) { + DeleteObject(wdev->hpens[i]); + DeleteObject(wdev->hbrushs[i]); + } + free(wdev->hpens); + free(wdev->hbrushs); + } + + + private void + win_update(gx_device_win *wdev, int amount) + { /* Update the image screen every 5 seconds, */ + /* checking the time every N scan lines. */ + static int fcount = 0; + static long time; + long date_time[2]; + + if (fcount == 0) + { gp_get_clock(date_time); + time = date_time[1]; + } + if ((fcount += amount) > 200 || fcount < 0) + { long deltatime; + gp_get_clock(date_time); + deltatime = date_time[1] - time; + if ( (deltatime > 5000L) || (deltatime < 0L) ) + { win_sync_output((gx_device *)wdev); /* time to redraw */ + time = date_time[1]; + } + fcount = 1; + } + } + + + long far PASCAL + WndProc(HWND hwnd, WORD message, WORD wParam, LONG lParam) + { gx_device_win *wdev; + HDC hdc, mem; + PAINTSTRUCT ps; + RECT rect; + HBITMAP bitmap; + HPALETTE oldpalette; + int nVscrollInc, nHscrollInc; + + /* Search the list of active Windows devices */ + /* to find the one owning this window. */ + for ( wdev = (gx_device_win *)gdev_win_open_list; + wdev != 0; wdev = wdev->next_wdev + ) + if ( wdev->hwndimg == hwnd ) break; + if ( wdev == 0 ) goto not_ours; /* can this happen??? */ + + switch(message) { + case WM_SYSCOMMAND: + switch(wParam) { + case M_COPY_CLIP: + /* make some where to put it and copy */ + bitmap = CreateCompatibleBitmap(wdev->hdcbit, wdev->width, + wdev->height); + if (bitmap) { + /* there is enough memory and the bitmaps OK */ + mem = CreateCompatibleDC(wdev->hdcbit); + SelectObject(mem, bitmap); + BitBlt(mem,0,0,wdev->width, + wdev->height, wdev->hdcbit, 0, 0, SRCCOPY); + DeleteDC(mem); + } + else { + puts("\nInsufficient Memory to Copy Clipboard"); + MessageBeep(0); + } + + OpenClipboard(hwnd); + EmptyClipboard(); + SetClipboardData(CF_BITMAP, bitmap); + CloseClipboard(); + + return 0; + } + break; + case WM_SIZE: + wdev->cyClient = HIWORD(lParam); + wdev->cxClient = LOWORD(lParam); + + wdev->cyAdjust = max(32,min(wdev->height, wdev->cyClient)) - wdev->cyClient; + wdev->cyClient += wdev->cyAdjust; + + wdev->nVscrollMax = max(0, wdev->height - wdev->cyClient); + wdev->nVscrollPos = min(wdev->nVscrollPos, wdev->nVscrollMax); + + SetScrollRange(hwnd, SB_VERT, 0, wdev->nVscrollMax, FALSE); + SetScrollPos(hwnd, SB_VERT, wdev->nVscrollPos, TRUE); + + wdev->cxAdjust = max(32,min(wdev->width, wdev->cxClient)) - wdev->cxClient; + wdev->cxClient += wdev->cxAdjust; + + wdev->nHscrollMax = max(0, wdev->width - wdev->cxClient); + wdev->nHscrollPos = min(wdev->nHscrollPos, wdev->nHscrollMax); + + SetScrollRange(hwnd, SB_HORZ, 0, wdev->nHscrollMax, FALSE); + SetScrollPos(hwnd, SB_HORZ, wdev->nHscrollPos, TRUE); + + if ((wParam==SIZENORMAL) && (wdev->cxAdjust!=0 || wdev->cyAdjust!=0)) { + GetWindowRect(hwnd,&rect); + MoveWindow(hwnd,rect.left,rect.top, + rect.right-rect.left+wdev->cxAdjust, + rect.bottom-rect.top+wdev->cyAdjust, TRUE); + wdev->cxAdjust = wdev->cyAdjust = 0; + } + return(0); + case WM_VSCROLL: + switch(wParam) { + case SB_TOP: + nVscrollInc = -wdev->nVscrollPos; + break; + case SB_BOTTOM: + nVscrollInc = wdev->nVscrollMax - wdev->nVscrollPos; + break; + case SB_LINEUP: + nVscrollInc = -wdev->cyClient/16; + break; + case SB_LINEDOWN: + nVscrollInc = wdev->cyClient/16; + break; + case SB_PAGEUP: + nVscrollInc = min(-1,-wdev->cyClient); + break; + case SB_PAGEDOWN: + nVscrollInc = max(1,wdev->cyClient); + break; + case SB_THUMBPOSITION: + nVscrollInc = LOWORD(lParam) - wdev->nVscrollPos; + break; + default: + nVscrollInc = 0; + } + if (nVscrollInc = max(-wdev->nVscrollPos, + min(nVscrollInc, wdev->nVscrollMax - wdev->nVscrollPos))) { + wdev->nVscrollPos += nVscrollInc; + ScrollWindow(hwnd,0,-nVscrollInc,NULL,NULL); + SetScrollPos(hwnd,SB_VERT,wdev->nVscrollPos,TRUE); + UpdateWindow(hwnd); + } + return(0); + case WM_HSCROLL: + switch(wParam) { + case SB_LINEUP: + nHscrollInc = -wdev->cxClient/16; + break; + case SB_LINEDOWN: + nHscrollInc = wdev->cyClient/16; + break; + case SB_PAGEUP: + nHscrollInc = min(-1,-wdev->cxClient); + break; + case SB_PAGEDOWN: + nHscrollInc = max(1,wdev->cxClient); + break; + case SB_THUMBPOSITION: + nHscrollInc = LOWORD(lParam) - wdev->nHscrollPos; + break; + default: + nHscrollInc = 0; + } + if (nHscrollInc = max(-wdev->nHscrollPos, + min(nHscrollInc, wdev->nHscrollMax - wdev->nHscrollPos))) { + wdev->nHscrollPos += nHscrollInc; + ScrollWindow(hwnd,-nHscrollInc,0,NULL,NULL); + SetScrollPos(hwnd,SB_HORZ,wdev->nHscrollPos,TRUE); + UpdateWindow(hwnd); + } + return(0); + case WM_KEYDOWN: + switch(wParam) { + case VK_HOME: + SendMessage(hwnd,WM_VSCROLL,SB_TOP,0L); + break; + case VK_END: + SendMessage(hwnd,WM_VSCROLL,SB_BOTTOM,0L); + break; + case VK_PRIOR: + SendMessage(hwnd,WM_VSCROLL,SB_PAGEUP,0L); + break; + case VK_NEXT: + SendMessage(hwnd,WM_VSCROLL,SB_PAGEDOWN,0L); + break; + case VK_UP: + SendMessage(hwnd,WM_VSCROLL,SB_LINEUP,0L); + break; + case VK_DOWN: + SendMessage(hwnd,WM_VSCROLL,SB_LINEDOWN,0L); + break; + case VK_LEFT: + SendMessage(hwnd,WM_HSCROLL,SB_PAGEUP,0L); + break; + case VK_RIGHT: + SendMessage(hwnd,WM_HSCROLL,SB_PAGEDOWN,0L); + break; + } + return(0); + case WM_PAINT: + { + int sx,sy,wx,wy,dx,dy; + hdc = BeginPaint(hwnd, &ps); + oldpalette = SelectPalette(hdc,wdev->himgpalette,NULL); + RealizePalette(hdc); + SetMapMode(hdc, MM_TEXT); + SetBkMode(hdc,OPAQUE); + GetClientRect(hwnd, &rect); + SetViewportExt(hdc, rect.right, rect.bottom); + dx = rect.left; /* destination */ + dy = rect.top; + wx = rect.right-rect.left; /* width */ + wy = rect.bottom-rect.top; + sx = rect.left; /* source */ + sy = rect.top; + sx += wdev->nHscrollPos; /* scrollbars */ + sy += wdev->nVscrollPos; + if (sx+wx > wdev->width) + wx = wdev->width - sx; + if (sy+wy > wdev->height) + wy = wdev->height - sy; + BitBlt(hdc,dx,dy,wx,wy,wdev->hdcbit,sx,sy,SRCCOPY); + SelectPalette(hdc,oldpalette,NULL); + EndPaint(hwnd, &ps); + return 0; + } + } + + not_ours: + return DefWindowProc((HWND)hwnd, (WORD)message, (WORD)wParam, (DWORD)lParam); + } diff -rc2N gs241/gdevpbm.c gs25/gdevpbm.c *** gs241/gdevpbm.c Sun Apr 12 14:53:38 1992 --- gs25/gdevpbm.c Wed Jun 24 16:55:42 1992 *************** *** 180,184 **** gdev_prn_bytes_per_scan_line((gx_device_printer *)bdev); byte *data = (byte *)gs_malloc(line_size, 1, "pbm_begin_page"); ! if ( data == 0 ) return -1; fprintf(pstream, "%s\n", bdev->magic); if ( bdev->comment[0] ) --- 180,185 ---- gdev_prn_bytes_per_scan_line((gx_device_printer *)bdev); byte *data = (byte *)gs_malloc(line_size, 1, "pbm_begin_page"); ! if ( data == 0 ) ! return_error(gs_error_VMerror); fprintf(pstream, "%s\n", bdev->magic); if ( bdev->comment[0] ) diff -rc2N gs241/gdevpccm.c gs25/gdevpccm.c *** gs241/gdevpccm.c Sat Apr 18 13:33:34 1992 --- gs25/gdevpccm.c Wed Aug 19 00:55:40 1992 *************** *** 79,82 **** --- 79,86 ---- /* Color mapping routines for 8-bit color with a fixed palette */ /* (3 bits of R, 3 bits of G, 2 bits of B). */ + /* We have to trade off even spacing of colors along each axis */ + /* against the desire to have real gray shades; */ + /* we compromise by using a 7x7x4 "cube" with extra gray shades */ + /* (1/6, 1/2, and 5/6), instead of the obvious 8x8x4. */ gx_color_index *************** *** 83,90 **** pc_8bit_map_rgb_color(gx_device *dev, gx_color_value r, gx_color_value g, gx_color_value b) ! { return (gx_color_index) ! (((r >> (gx_color_value_bits - 3)) << 5) + ! ((g >> (gx_color_value_bits - 3)) << 2) + ! ((b >> (gx_color_value_bits - 2)))); } int --- 87,96 ---- pc_8bit_map_rgb_color(gx_device *dev, gx_color_value r, gx_color_value g, gx_color_value b) ! { uint rv = r / (gx_max_color_value / 7 + 1); ! uint gv = g / (gx_max_color_value / 7 + 1); ! uint bv = b / (gx_max_color_value / 7 + 1); ! return (gx_color_index) ! (rv == gv && gv == bv ? rv + (256-7) : ! (rv << 5) + (gv << 2) + (bv >> 1)); } int *************** *** 91,99 **** pc_8bit_map_color_rgb(gx_device *dev, gx_color_index color, gx_color_value prgb[3]) ! { #define icolor (uint)color ! prgb[0] = ((icolor >> 5) & 7) * (gx_max_color_value / 7); ! prgb[1] = ((icolor >> 2) & 7) * (gx_max_color_value / 7); ! prgb[2] = (icolor & 3) * (gx_max_color_value / 3); #undef icolor return 0; --- 97,117 ---- pc_8bit_map_color_rgb(gx_device *dev, gx_color_index color, gx_color_value prgb[3]) ! { static const gx_color_value ramp[8] = ! { 0, gx_max_color_value / 6, gx_max_color_value / 3, ! gx_max_color_value / 2, 2 * (gx_max_color_value / 3), ! 5 * (gx_max_color_value / 6), gx_max_color_value, ! /* The 8th entry is not actually ever used, */ ! /* except to fill out the palette. */ ! gx_max_color_value ! }; #define icolor (uint)color ! if ( icolor >= 256-7 ) ! { prgb[0] = prgb[1] = prgb[2] = ramp[icolor - (256-7)]; ! } ! else ! { prgb[0] = ramp[(icolor >> 5) & 7]; ! prgb[1] = ramp[(icolor >> 2) & 7]; ! prgb[2] = ramp[(icolor & 3) << 1]; ! } #undef icolor return 0; *************** *** 113,115 **** } return 0; ! } \ No newline at end of file --- 131,133 ---- } return 0; ! } diff -rc2N gs241/gdevpcfb.c gs25/gdevpcfb.c *** gs241/gdevpcfb.c Fri Feb 21 02:47:14 1992 --- gs25/gdevpcfb.c Sat Aug 15 09:11:08 1992 *************** *** 25,85 **** /* that allow it to drive larger displays. */ #include "memory_.h" ! #include "gs.h" #include "gxdevice.h" - #ifndef USE_ASM - # define USE_ASM 0 /* don't use assembly language */ - #endif - - /* Define the short (integer) version of "transparent" color. */ - /* ****** Depends on gx_no_color_index being all 1's. ******/ - #define no_color ((int)gx_no_color_index) - - /* For testing, the EGA may be defined as a monochrome, 8-color, or */ - /* 16-color device. */ - #define ega_bits_of_color 2 /* 0, 1, or 2 */ - - /* Range of r-g-b values */ - #define rgb_max ega_bits_of_color - - /* Procedures */ - - /* See gxdevice.h for the definitions of the procedures. */ - - dev_proc_open_device(ega_open); - dev_proc_close_device(ega_close); - dev_proc_map_rgb_color(ega_map_rgb_color); - dev_proc_map_color_rgb(ega_map_color_rgb); - dev_proc_fill_rectangle(ega_fill_rectangle); - dev_proc_tile_rectangle(ega_tile_rectangle); - int ega_write_dot(P4(gx_device *, int, int, gx_color_index)); - dev_proc_copy_mono(ega_copy_mono); - dev_proc_copy_color(ega_copy_color); - dev_proc_get_bits(ega_get_bits); - - /* Type for frame buffer pointers. */ - /* Note that 'far' gets defined as null on 32-bit systems. */ - typedef byte far *fb_ptr; - - /* The device descriptor */ - typedef struct gx_device_ega_s gx_device_ega; - struct gx_device_ega_s { - gx_device_common; - int raster; /* frame buffer bytes per line */ - int fb_seg_mult; /* multiplier for segment part */ - /* of frame buffer pointer */ - int fb_byte_mult; /* multiplier for word part ditto */ - #define mk_fb_ptr(x, y)\ - (fb_dev->fb_byte_mult == 0 ?\ - (fb_ptr)MK_PTR(regen + (y) * (fb_dev->fb_seg_mult), (x) >> 3) :\ - (fb_ptr)MK_PTR(regen + ((y) >> 4) * (fb_dev->fb_seg_mult),\ - (((y) & 15) * fb_dev->fb_byte_mult) + ((x) >> 3))) - /* Define the largest height that can be processed */ - /* within a single 64K segment. If fb_dev->height > max_rop_height, */ - /* we may have to break up operations into pieces. */ - unsigned max_rop_height; - int video_mode; - }; - /* Macro for casting gx_device argument */ #define fb_dev ((gx_device_ega *)dev) --- 25,33 ---- /* that allow it to drive larger displays. */ #include "memory_.h" ! #include "gx.h" ! #include "gserrors.h" #include "gxdevice.h" + #include "gdevpcfb.h" /* Macro for casting gx_device argument */ #define fb_dev ((gx_device_ega *)dev) *************** *** 104,150 **** }; - /* Macro for creating instances */ - /* The initial parameters map an appropriate fraction of */ - /* the screen to an 8.5" x 11" coordinate space. */ - /* This may or may not be what is desired! */ - #define ega_device(dev_name, fb_raster, screen_height, aspect_ratio, video_mode)\ - { sizeof(gx_device_ega),\ - &ega_procs,\ - dev_name,\ - fb_raster * 8, screen_height,\ - (screen_height * (aspect_ratio)) / 11.0, /* x density */\ - screen_height / 11.0, /* y density */\ - no_margins,\ - { (rgb_max ? 3 : 1), /* num_components */\ - 4, /* depth */\ - (rgb_max ? rgb_max : 1), /* gray_max */\ - rgb_max,\ - 3, /* dither_gray */\ - (rgb_max ? rgb_max + 1 : 0) /* dither_rgb */\ - },\ - 0, /* not opened yet */\ - fb_raster,\ - (fb_raster & 15 ? fb_raster : fb_raster >> 4),\ - (fb_raster & 15 ? fb_raster : 0),\ - ((unsigned)(0xffff - fb_raster) / fb_raster),\ - video_mode\ - } - /* All the known instances */ /* EGA */ gx_device_ega gs_ega_device = ! ega_device("ega", 80, 350, 48.0/35.0, 0x10); /* VGA */ gx_device_ega gs_vga_device = ! ega_device("vga", 80, 480, 1.0, 0x12); /* Trident SuperVGA, 800x600, 16-color mode */ gx_device_ega gs_tvga16_device = ! ega_device("tvga16", 100, 600, 1.0, 0x5b); /* Tseng Labs SuperVGA, 800x600, 16-color mode */ gx_device_ega gs_tseng16_device = ! ega_device("tseng16", 100, 600, 1.0, 0x29); /* EIZO MDB-10 */ gx_device_ega gs_mdb10_device = ! ega_device("mdb10", 128, 768, 1.0, 0x37); /* Define the color spectrum */ --- 52,71 ---- }; /* All the known instances */ /* EGA */ gx_device_ega gs_ega_device = ! ega_device("ega", ega_procs, 80, 350, 48.0/35.0, 0x10); /* VGA */ gx_device_ega gs_vga_device = ! ega_device("vga", ega_procs, 80, 480, 1.0, 0x12); /* Trident SuperVGA, 800x600, 16-color mode */ gx_device_ega gs_tvga16_device = ! ega_device("tvga16", ega_procs, 100, 600, 1.0, 0x5b); /* Tseng Labs SuperVGA, 800x600, 16-color mode */ gx_device_ega gs_tseng16_device = ! ega_device("tseng16", ega_procs, 100, 600, 1.0, 0x29); /* EIZO MDB-10 */ gx_device_ega gs_mdb10_device = ! ega_device("mdb10", ega_procs, 128, 768, 1.0, 0x37); /* Define the color spectrum */ *************** *** 239,247 **** } - /* Macro for validating rectangle parameters x, y, w, h */ - #define validate_rect()\ - if ( w <= 0 || h <= 0 ) return 0;\ - if ( x < 0 || y < 0 || x + w > dev->width || y + h > dev->height ) return -1 - /* ------ Internal routines ------ */ --- 160,163 ---- *************** *** 270,274 **** fb_ptr dest; /* pointer to frame buffer */ int draster; /* raster of frame buffer */ ! byte far *src; /* pointer to source data */ int sraster; /* source raster */ int width; /* width in bytes */ --- 186,190 ---- fb_ptr dest; /* pointer to frame buffer */ int draster; /* raster of frame buffer */ ! const byte far *src; /* pointer to source data */ int sraster; /* source raster */ int width; /* width in bytes */ *************** *** 340,344 **** private void cmemrwcol(rop_ptr rop) ! { byte far *dp = rop->dest, *sp = rop->src; int yc = rop->height; int shift = rop->shift; --- 256,261 ---- private void cmemrwcol(rop_ptr rop) ! { byte far *dp = rop->dest; ! const byte far *sp = rop->src; int yc = rop->height; int shift = rop->shift; *************** *** 353,357 **** private void cmemrwcol0(rop_ptr rop) ! { byte far *dp = rop->dest, *sp = rop->src; int yc = rop->height; byte invert = rop->invert; --- 270,275 ---- private void cmemrwcol0(rop_ptr rop) ! { byte far *dp = rop->dest; ! const byte far *sp = rop->src; int yc = rop->height; byte invert = rop->invert; *************** *** 372,376 **** private void cmemrwcol2(rop_ptr rop) ! { byte far *dp = rop->dest, *sp = rop->src; int yc = rop->height; int shift = rop->shift; --- 290,295 ---- private void cmemrwcol2(rop_ptr rop) ! { byte far *dp = rop->dest; ! const byte far *sp = rop->src; int yc = rop->height; int shift = rop->shift; *************** *** 386,418 **** /* Forward definitions */ ! void fill_rectangle(P4(rop_ptr, int, int, int)); ! void fill_row(P3(byte far *, int, int)); ! ! /* Define the device port and register numbers, and the regen map base */ ! #define out2(port, index, data)\ ! (outportb(port, index), outportb((port)+1, data)) ! #define seq_addr 0x3c4 ! #define s_map 2 ! #define set_s_map(mask) out2(seq_addr, s_map, mask) ! #define graph_addr 0x3ce ! #define g_const 0 /* set/reset */ ! #define set_g_const(color) out2(graph_addr, g_const, color) ! #define g_const_map 1 /* enable set/reset */ ! #define set_g_const_map(map) out2(graph_addr, g_const_map, map) ! #define g_function 3 ! #define set_g_function(func) out2(graph_addr, g_function, func) ! #define g_read_plane 4 ! #define set_g_read_plane(plane) out2(graph_addr, g_read_plane, plane) ! # define gf_WRITE 0 ! # define gf_AND 8 ! # define gf_OR 0x10 ! # define gf_XOR 0x18 ! #define g_mode 5 ! #define set_g_mode(mode) out2(graph_addr, g_mode, mode) ! # define gm_DATA 0 ! # define gm_FILL 2 ! #define g_mask 8 ! #define set_g_mask(mask) out2(graph_addr, g_mask, mask) ! #define regen 0xa000 /* Clean up after writing */ --- 305,311 ---- /* Forward definitions */ ! int ega_write_dot(P4(gx_device *, int, int, gx_color_index)); ! private void near fill_rectangle(P4(rop_ptr, int, int, int)); ! private void near fill_row_only(P4(byte far *, int, int, int)); /* Clean up after writing */ *************** *** 423,427 **** int ega_open(gx_device *dev) ! { if ( ega_save_mode < 0 ) ega_save_mode = ega_get_mode(); ega_set_mode(fb_dev->video_mode); set_s_map(-1); /* enable all maps */ --- 316,334 ---- int ega_open(gx_device *dev) ! { /* Adjust the device resolution. */ ! /* This is a hack, pending refactoring of the put_props machinery. */ ! switch ( fb_dev->video_mode ) ! { ! case 0x10: /* EGA */ ! gx_device_adjust_resolution(dev, 640, 350); break; ! case 0x12: /* VGA */ ! gx_device_adjust_resolution(dev, 640, 480); break; ! case 0x5b: /* Trident */ ! case 0x29: /* Tseng */ ! gx_device_adjust_resolution(dev, 800, 600); break; ! case 0x37: /* EIZO */ ! gx_device_adjust_resolution(dev, 1024, 768); break; ! } ! if ( ega_save_mode < 0 ) ega_save_mode = ega_get_mode(); ega_set_mode(fb_dev->video_mode); set_s_map(-1); /* enable all maps */ *************** *** 433,438 **** int ega_write_dot(gx_device *dev, int x, int y, gx_color_index color) ! { byte data = (byte)color; ! return ega_copy_color(dev, &data, 1, 1, gx_no_bitmap_id, x, y, 1, 1); } --- 340,346 ---- int ega_write_dot(gx_device *dev, int x, int y, gx_color_index color) ! { byte data[4]; ! data[0] = (byte)color; ! return ega_copy_color(dev, data, 1, 4, gx_no_bitmap_id, x, y, 1, 1); } *************** *** 444,448 **** int ega_copy_mono(gx_device *dev, ! byte *base, int sourcex, int raster, gx_bitmap_id id, int x, int y, int w, int h, gx_color_index izero, gx_color_index ione) { rop_params params; --- 352,356 ---- int ega_copy_mono(gx_device *dev, ! const byte *base, int sourcex, int raster, gx_bitmap_id id, int x, int y, int w, int h, gx_color_index izero, gx_color_index ione) { rop_params params; *************** *** 577,581 **** /* Do center */ if ( (count -= 8) >= 0 ) ! { set_g_mask(0xff); do { params.src++, params.dest++; --- 485,489 ---- /* Do center */ if ( (count -= 8) >= 0 ) ! { out_g_mask(0xff); do { params.src++, params.dest++; *************** *** 587,591 **** if ( rmask ) { params.src++, params.dest++; ! set_g_mask(rmask); memrwcol0((rop_ptr)¶ms); } --- 495,499 ---- if ( rmask ) { params.src++, params.dest++; ! out_g_mask(rmask); memrwcol0((rop_ptr)¶ms); } *************** *** 609,613 **** /* Do center */ if ( (count -= 8) >= 0 ) ! { set_g_mask(0xff); do { params.dest++; --- 517,521 ---- /* Do center */ if ( (count -= 8) >= 0 ) ! { out_g_mask(0xff); do { params.dest++; *************** *** 619,623 **** /* Do right column */ if ( rmask ) ! { set_g_mask(rmask); params.dest++; if ( count + 8 <= params.shift ) --- 527,531 ---- /* Do right column */ if ( rmask ) ! { out_g_mask(rmask); params.dest++; if ( count + 8 <= params.shift ) *************** *** 656,662 **** int ega_copy_color(gx_device *dev, ! byte *base, int sourcex, int raster, gx_bitmap_id id, int x, int y, int w, int h) ! { byte *line = base + (sourcex >> 1); unsigned lmask = 0x80 >> (x & 7); int bitx = sourcex & 1; --- 564,570 ---- int ega_copy_color(gx_device *dev, ! const byte *base, int sourcex, int raster, gx_bitmap_id id, int x, int y, int w, int h) ! { const byte *line = base + (sourcex >> 1); unsigned lmask = 0x80 >> (x & 7); int bitx = sourcex & 1; *************** *** 669,673 **** x, y, w, mrh); if ( code != 0 ) return code; ! base = (byte *)((byte huge *)base + raster * (long)mrh); id = gx_no_bitmap_id; --- 577,581 ---- x, y, w, mrh); if ( code != 0 ) return code; ! base = (const byte *)((const byte huge *)base + raster * (long)mrh); id = gx_no_bitmap_id; *************** *** 677,683 **** fbline = mk_fb_ptr(x, y); set_g_mode(gm_FILL); ! outportb(graph_addr, g_mask); /* first half of set_g_mask */ while ( --h >= 0 ) ! { byte *bptr = line; int px = bitx; /* Turbo C will put an unsigned in a register, */ --- 585,591 ---- fbline = mk_fb_ptr(x, y); set_g_mode(gm_FILL); ! select_g_mask(); while ( --h >= 0 ) ! { const byte *bptr = line; int px = bitx; /* Turbo C will put an unsigned in a register, */ *************** *** 687,691 **** do { byte_discard(*fbptr); /* latch frame buffer data */ ! outportb(graph_addr+1, mask); /* 2nd half of set_g_mask */ *fbptr = (px & 1 ? *bptr++ & 0xf : *bptr >> 4); if ( (mask >>= 1) == 0 ) --- 595,599 ---- do { byte_discard(*fbptr); /* latch frame buffer data */ ! out_g_mask(mask); *fbptr = (px & 1 ? *bptr++ & 0xf : *bptr >> 4); if ( (mask >>= 1) == 0 ) *************** *** 717,723 **** params.dest = mk_fb_ptr(x, y); if ( h == 1 ) ! { set_g_const((int)color); ! fill_row(params.dest, x & 7, w); ! } else { params.draster = fb_dev->raster; --- 625,629 ---- params.dest = mk_fb_ptr(x, y); if ( h == 1 ) ! fill_row_only(params.dest, x & 7, w, (int)color); else { params.draster = fb_dev->raster; *************** *** 724,729 **** params.height = h; fill_rectangle((rop_ptr)¶ms, x & 7, w, (int)color); } - dot_end(); return 0; } --- 630,635 ---- params.height = h; fill_rectangle((rop_ptr)¶ms, x & 7, w, (int)color); + dot_end(); } return 0; } *************** *** 733,737 **** /* a transparent color means that the tile is colored, not a mask. */ int ! ega_tile_rectangle(gx_device *dev, gx_bitmap *tile, int x, int y, int w, int h, gx_color_index czero, gx_color_index cone, int px, int py) --- 639,643 ---- /* a transparent color means that the tile is colored, not a mask. */ int ! ega_tile_rectangle(gx_device *dev, const gx_bitmap *tile, int x, int y, int w, int h, gx_color_index czero, gx_color_index cone, int px, int py) *************** *** 923,927 **** /* starting bit within byte, width, and height. */ /* Smashes rop->dest. */ ! private void fill_rectangle(register rop_ptr rop, int bit, int w, int color) /* rop: dest, draster, height */ --- 829,833 ---- /* starting bit within byte, width, and height. */ /* Smashes rop->dest. */ ! private void near fill_rectangle(register rop_ptr rop, int bit, int w, int color) /* rop: dest, draster, height */ *************** *** 928,934 **** { set_g_const(color); set_g_const_map(0xf); if ( bit + w <= 8 ) { /* Less than one byte */ ! set_g_mask(rmask_tab[w] >> bit); memsetcol(rop); } --- 834,841 ---- { set_g_const(color); set_g_const_map(0xf); + select_g_mask(); if ( bit + w <= 8 ) { /* Less than one byte */ ! out_g_mask(rmask_tab[w] >> bit); memsetcol(rop); } *************** *** 936,940 **** { byte right_mask; if ( bit ) ! { set_g_mask(0xff >> bit); memsetcol(rop); rop->dest++; --- 843,847 ---- { byte right_mask; if ( bit ) ! { out_g_mask(0xff >> bit); memsetcol(rop); rop->dest++; *************** *** 942,946 **** } if ( w >= 8 ) ! { set_g_mask(0xff); /* all bits */ rop->width = w >> 3; memsetrect(rop); --- 849,853 ---- } if ( w >= 8 ) ! { out_g_mask(0xff); /* all bits */ rop->width = w >> 3; memsetrect(rop); *************** *** 949,953 **** } if ( (right_mask = rmask_tab[w]) != 0 ) ! { set_g_mask(right_mask); memsetcol(rop); } --- 856,860 ---- } if ( (right_mask = rmask_tab[w]) != 0 ) ! { out_g_mask(right_mask); memsetcol(rop); } *************** *** 957,976 **** /* Fill a single row specified by pointer into frame buffer, */ ! /* starting bit within byte, and width. */ ! /* Caller has already set g_const. */ #define r_m_w(ptr) (*(ptr))++ /* read & write, data irrelevant */ ! private void ! fill_row(byte far *dest, int bit, int w) /* rop: dest */ ! { set_g_const_map(0xf); ! if ( bit + w <= 8 ) ! { /* Less than one byte */ ! set_g_mask(rmask_tab[w] >> bit); ! r_m_w(dest); } else { byte right_mask; if ( bit ) ! { set_g_mask(0xff >> bit); r_m_w(dest); dest++; --- 864,906 ---- /* Fill a single row specified by pointer into frame buffer, */ ! /* starting bit within byte, and width; clean up afterwards. */ #define r_m_w(ptr) (*(ptr))++ /* read & write, data irrelevant */ ! private void near ! fill_row_only(byte far *dest, int bit, int w, int color) /* rop: dest */ ! { if ( bit + w <= 8 ) ! { /* Less than one byte. */ ! /* Optimize filling with black or white. */ ! switch ( color ) ! { ! case 0: ! set_g_mask(rmask_tab[w] >> bit); ! *dest &= color; /* read, then write 0s; */ ! /* some compilers optimize &= 0 to a store. */ ! out_g_mask(0xff); /* dot_end */ ! break; ! case 0xf: ! set_g_mask(rmask_tab[w] >> bit); ! *dest |= 0xff; /* read, then write 1s; */ ! /* some compilers optimize &= 0 to a store. */ ! out_g_mask(0xff); /* dot_end */ ! break; ! default: ! set_g_const(color); ! set_g_const_map(0xf); ! set_g_mask(rmask_tab[w] >> bit); ! r_m_w(dest); ! out_g_mask(0xff); /* dot_end */ ! set_g_const_map(0); ! } } else { byte right_mask; + int byte_count; + set_g_const(color); + set_g_const_map(0xf); + select_g_mask(); if ( bit ) ! { out_g_mask(0xff >> bit); r_m_w(dest); dest++; *************** *** 977,992 **** w += bit - 8; } ! if ( w >= 8 ) ! { int byte_count = w >> 3; ! set_g_mask(0xff); /* all bits */ ! memset(dest, 0, byte_count); /* data irrelevant */ ! dest += byte_count; ! w &= 7; ! } ! if ( (right_mask = rmask_tab[w]) != 0 ) ! { set_g_mask(right_mask); ! r_m_w(dest); } } - set_g_const_map(0); } --- 907,920 ---- w += bit - 8; } ! byte_count = w >> 3; ! if ( (right_mask = rmask_tab[w & 7]) != 0 ) ! { out_g_mask(right_mask); ! r_m_w(dest + byte_count); ! } ! out_g_mask(0xff); ! if ( byte_count ) ! { memset(dest, 0, byte_count); /* data irrelevant */ } + set_g_const_map(0); } } diff -rc2N gs241/gdevpcfb.h gs25/gdevpcfb.h *** gs241/gdevpcfb.h --- gs25/gdevpcfb.h Sat Jul 25 03:27:22 1992 *************** *** 0 **** --- 1,139 ---- + /* Copyright (C) 1989, 1992 Aladdin Enterprises. All rights reserved. + Distributed by Free Software Foundation, Inc. + + This file is part of Ghostscript. + + Ghostscript is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY. No author or distributor accepts responsibility + to anyone for the consequences of using it or for whether it serves any + particular purpose or works at all, unless he says so in writing. Refer + to the Ghostscript General Public License for full details. + + Everyone is granted permission to copy, modify and redistribute + Ghostscript, but only under the conditions described in the Ghostscript + General Public License. A copy of this license is supposed to have been + given to you along with Ghostscript so you can know your rights and + responsibilities. It should be in a file named COPYING. Among other + things, the copyright notice and this notice must be preserved on all + copies. */ + + /* gdevpcfb.h */ + /* IBM PC frame buffer definitions for Ghostscript */ + /* (requires dos_.h) */ + + /* For testing, the 16-color display may be defined as a monochrome, */ + /* 8-color, or 16-color device. */ + #define ega_bits_of_color 2 /* 0, 1, or 2 */ + + /* Range of r-g-b values */ + #define rgb_max ega_bits_of_color + + #ifndef USE_ASM + # define USE_ASM 0 /* don't use assembly language */ + #endif + + /* Define the short (integer) version of "transparent" color. */ + /* ****** Depends on gx_no_color_index being all 1's. ******/ + #define no_color ((int)gx_no_color_index) + + /* Procedures */ + + /* See gxdevice.h for the definitions of the procedures. */ + + extern dev_proc_open_device(ega_open); + extern dev_proc_close_device(ega_close); + extern dev_proc_map_rgb_color(ega_map_rgb_color); + extern dev_proc_map_color_rgb(ega_map_color_rgb); + extern dev_proc_fill_rectangle(ega_fill_rectangle); + extern dev_proc_tile_rectangle(ega_tile_rectangle); + extern dev_proc_copy_mono(ega_copy_mono); + extern dev_proc_copy_color(ega_copy_color); + extern dev_proc_get_bits(ega_get_bits); + + /* Type for frame buffer pointers. */ + /* Note that 'far' gets defined as null on 32-bit systems. */ + typedef byte far *fb_ptr; + + /* The device descriptor */ + typedef struct gx_device_ega_s gx_device_ega; + struct gx_device_ega_s { + gx_device_common; + int raster; /* frame buffer bytes per line */ + int fb_seg_mult; /* multiplier for segment part */ + /* of frame buffer pointer */ + int fb_byte_mult; /* multiplier for word part ditto */ + #define mk_fb_ptr(x, y)\ + (fb_dev->fb_byte_mult == 0 ?\ + (fb_ptr)MK_PTR(regen + (y) * (fb_dev->fb_seg_mult), (x) >> 3) :\ + (fb_ptr)MK_PTR(regen + ((y) >> 4) * (fb_dev->fb_seg_mult),\ + (((y) & 15) * fb_dev->fb_byte_mult) + ((x) >> 3))) + /* Define the largest height that can be processed */ + /* within a single 64K segment. If fb_dev->height > max_rop_height, */ + /* we may have to break up operations into pieces. */ + unsigned max_rop_height; + int video_mode; + }; + + /* Macro for creating instances */ + /* The initial parameters map an appropriate fraction of */ + /* the screen to an 8.5" x 11" coordinate space. */ + /* This may or may not be what is desired! */ + #define ega_device(dev_name, procs, fb_raster, screen_height, aspect_ratio, video_mode)\ + { sizeof(gx_device_ega),\ + &procs,\ + dev_name,\ + fb_raster * 8, screen_height,\ + (screen_height * (aspect_ratio)) / 11.0, /* x density */\ + screen_height / 11.0, /* y density */\ + no_margins,\ + { (rgb_max ? 3 : 1), /* num_components */\ + 4, /* depth */\ + (rgb_max ? rgb_max : 1), /* gray_max */\ + rgb_max,\ + 3, /* dither_gray */\ + (rgb_max ? rgb_max + 1 : 0) /* dither_rgb */\ + },\ + 0, /* not opened yet */\ + fb_raster,\ + (fb_raster & 15 ? fb_raster : fb_raster >> 4),\ + (fb_raster & 15 ? fb_raster : 0),\ + ((unsigned)(0xffff - fb_raster) / fb_raster),\ + video_mode\ + } + + /* Define the device port and register numbers, and the regen map base */ + #define out2(port, index, data)\ + (outportb(port, index), outportb((port)+1, data)) + #define outin2(port, index)\ + (outportb(port, index), inportb((port)+1)) + #define seq_addr 0x3c4 + #define s_map 2 + #define set_s_map(mask) out2(seq_addr, s_map, mask) + #define graph_addr 0x3ce + #define g_const 0 /* set/reset */ + #define set_g_const(color) out2(graph_addr, g_const, color) + #define g_const_map 1 /* enable set/reset */ + #define set_g_const_map(map) out2(graph_addr, g_const_map, map) + #define g_function 3 + #define set_g_function(func) out2(graph_addr, g_function, func) + #define g_read_plane 4 + #define set_g_read_plane(plane) out2(graph_addr, g_read_plane, plane) + # define gf_WRITE 0 + # define gf_AND 8 + # define gf_OR 0x10 + # define gf_XOR 0x18 + #define g_mode 5 + #define set_g_mode(mode) out2(graph_addr, g_mode, mode) + # define gm_DATA 0 + # define gm_FILL 2 + #define g_mask 8 + #define set_g_mask(mask) out2(graph_addr, g_mask, mask) + #define select_g_mask() outportb(graph_addr, g_mask) + #define out_g_mask(mask) outportb(graph_addr+1, mask) + #define regen 0xa000 + + /* Macro for validating rectangle parameters x, y, w, h */ + #define validate_rect()\ + if ( w <= 0 || h <= 0 ) return 0;\ + if ( x < 0 || y < 0 || x + w > dev->width || y + h > dev->height )\ + return_error(gs_error_rangecheck) diff -rc2N gs241/gdevpcl.c gs25/gdevpcl.c *** gs241/gdevpcl.c Thu Mar 5 16:41:00 1992 --- gs25/gdevpcl.c Sat Aug 15 11:06:32 1992 *************** *** 23,26 **** --- 23,59 ---- #include "gdevpcl.h" + /* ------ Get paper size ------ */ + + /* Get the paper size code, based on width and height. */ + int + gdev_pcl_paper_size(gx_device *dev) + { return + (dev->height / dev->y_pixels_per_inch >= 11.8 ? PAPER_SIZE_LEGAL : + dev->height / dev->y_pixels_per_inch >= 11.1 ? PAPER_SIZE_A4 : + PAPER_SIZE_LETTER); + } + + /* ------ Get initial matrix ------ */ + + /* Get an initial matrix adjusted for the margins. */ + + /* + * PCL has the notion of a LOGICAL and a PHYSICAL page. The PHYSICAL page is + * the actual paper; the LOGICAL page is the printer specific imageable area. + * The strange part is that coordinates are all relative to the + * LOGICAL page. This means that all PCL code is inherently device dependent. + * Luckily, in PostScript land, transformation matrices conquer all. + */ + + void + gdev_pcl_get_initial_matrix(gx_device *dev, gs_matrix *pmat) + { pmat->xx = dev->x_pixels_per_inch / 72.0; + pmat->xy = 0; + pmat->yx = 0; + pmat->yy = dev->y_pixels_per_inch / -72.0; + pmat->tx = -(dev->l_margin * dev->x_pixels_per_inch); + pmat->ty = dev->height - (dev->t_margin * dev->y_pixels_per_inch); + } + /* ------ Color mapping ------ */ diff -rc2N gs241/gdevpcl.h gs25/gdevpcl.h *** gs241/gdevpcl.h Thu Mar 5 16:35:16 1992 --- gs25/gdevpcl.h Sat Aug 15 06:05:32 1992 *************** *** 22,25 **** --- 22,36 ---- /* Requires gdevprn.h */ + /* Define the PCL paper size codes. */ + #define PAPER_SIZE_LETTER 2 + #define PAPER_SIZE_LEGAL 3 + #define PAPER_SIZE_A4 26 + + /* Get the paper size code, based on width and height. */ + extern int gdev_pcl_paper_size(P1(gx_device *)); + + /* Get initial matrix, adjusting for margins. */ + extern dev_proc_get_initial_matrix(gdev_pcl_get_initial_matrix); + /* Color mapping procedures for 3-bit-per-pixel RGB printers */ extern dev_proc_map_rgb_color(gdev_pcl_3bit_map_rgb_color); diff -rc2N gs241/gdevpcx.c gs25/gdevpcx.c *** gs241/gdevpcx.c Sat Apr 18 13:32:28 1992 --- gs25/gdevpcx.c Tue Jul 21 05:39:24 1992 *************** *** 21,25 **** /* PCX file format devices for Ghostscript */ #include "gdevprn.h" - #include "gserrors.h" /* REALLY? */ #include "gdevpccm.h" --- 21,24 ---- *************** *** 83,86 **** --- 82,92 ---- /* ------ Private definitions ------ */ + /* All two-byte quantities are stored LSB-first! */ + #if arch_is_big_endian + # define assign_ushort(a,v) a = ((v) >> 8) + ((v) << 8) + #else + # define assign_ushort(a,v) a = (v) + #endif + typedef struct pcx_header_s { byte manuf; /* always 0x0a */ *************** *** 115,123 **** /* Forward declarations */ ! private void pcx_write_rle(P3(byte *, byte *, FILE *)); private int pcx_write_page(P4(gx_device_printer *, FILE *, pcx_header _ss *, int)); /* Write an "old" PCX page. */ ! static byte ega_palette[16*3] = { 0x00,0x00,0x00, 0x00,0x00,0xaa, 0x00,0xaa,0x00, 0x00,0xaa,0xaa, 0xaa,0x00,0x00, 0xaa,0x00,0xaa, 0xaa,0xaa,0x00, 0xaa,0xaa,0xaa, --- 121,129 ---- /* Forward declarations */ ! private void pcx_write_rle(P3(const byte *, const byte *, FILE *)); private int pcx_write_page(P4(gx_device_printer *, FILE *, pcx_header _ss *, int)); /* Write an "old" PCX page. */ ! static const byte ega_palette[16*3] = { 0x00,0x00,0x00, 0x00,0x00,0xaa, 0x00,0xaa,0x00, 0x00,0xaa,0xaa, 0xaa,0x00,0x00, 0xaa,0x00,0xaa, 0xaa,0xaa,0x00, 0xaa,0xaa,0xaa, *************** *** 183,187 **** int code = 0; /* return code */ if ( row == 0 ) /* can't allocate row buffer */ ! return gs_error_VMerror; /* setup the header struct */ --- 189,193 ---- int code = 0; /* return code */ if ( row == 0 ) /* can't allocate row buffer */ ! return_error(gs_error_VMerror); /* setup the header struct */ *************** *** 192,203 **** phdr->x1 = 0; phdr->y1 = 0; ! phdr->x2 = pdev->width-1; ! phdr->y2 = height-1; ! phdr->hres = (int)pdev->x_pixels_per_inch; ! phdr->vres = (int)pdev->y_pixels_per_inch; phdr->vmode = 0; /* nplanes was set by the caller */ ! phdr->bpl = (planar && depth > 1 ? rsize : raster); ! phdr->palinfo = (gx_device_has_color(pdev) ? 1 : 2); /* Write the header. */ --- 198,209 ---- phdr->x1 = 0; phdr->y1 = 0; ! assign_ushort(phdr->x2, pdev->width-1); ! assign_ushort(phdr->y2, height-1); ! assign_ushort(phdr->hres, (int)pdev->x_pixels_per_inch); ! assign_ushort(phdr->vres, (int)pdev->y_pixels_per_inch); phdr->vmode = 0; /* nplanes was set by the caller */ ! assign_ushort(phdr->bpl, (planar && depth > 1 ? rsize : raster)); ! assign_ushort(phdr->palinfo, (gx_device_has_color(pdev) ? 1 : 2)); /* Write the header. */ *************** *** 275,279 **** /* Write one line in PCX run-length-encoded format. */ private void ! pcx_write_rle(byte *from, byte *end, FILE *file) { while ( from < end ) { byte data = *from++; --- 281,285 ---- /* Write one line in PCX run-length-encoded format. */ private void ! pcx_write_rle(const byte *from, const byte *end, FILE *file) { while ( from < end ) { byte data = *from++; diff -rc2N gs241/gdevpe.c gs25/gdevpe.c *** gs241/gdevpe.c Sun Feb 16 18:21:12 1992 --- gs25/gdevpe.c Thu Jun 4 16:04:04 1992 *************** *** 21,24 **** --- 21,25 ---- Hacked by Fran Taylor, Reflection Technology Inc. */ + #include "memory_.h" #include "gx.h" #include "gxdevice.h" *************** *** 226,234 **** int pe_copy_mono(gx_device *dev, ! byte *base, int sourcex, int raster, gx_bitmap_id id, int x, int y, int w, int h, gx_color_index zero, gx_color_index one) { ! byte *line; int sleft, dleft; int mask, rmask; --- 227,235 ---- int pe_copy_mono(gx_device *dev, ! const byte *base, int sourcex, int raster, gx_bitmap_id id, int x, int y, int w, int h, gx_color_index zero, gx_color_index one) { ! const byte *line; int sleft, dleft; int mask, rmask; *************** *** 285,289 **** while ( --h >= 0 ) { ! register byte *bptr = line; int count = w; register byte *optr = dest; --- 286,290 ---- while ( --h >= 0 ) { ! register const byte *bptr = line; int count = w; register byte *optr = dest; *************** *** 320,324 **** while (--h >= 0) { ! byte *bptr = line; int count = w; byte *optr = dest; --- 321,325 ---- while (--h >= 0) { ! const byte *bptr = line; int count = w; byte *optr = dest; diff -rc2N gs241/gdevpjet.c gs25/gdevpjet.c *** gs241/gdevpjet.c Wed Mar 25 10:36:36 1992 --- gs25/gdevpjet.c Sun Aug 2 15:50:56 1992 *************** *** 1,3 **** ! /* Copyright (C) 1991 Aladdin Enterprises. All rights reserved. Distributed by Free Software Foundation, Inc. --- 1,3 ---- ! /* Copyright (C) 1991, 1992 Aladdin Enterprises. All rights reserved. Distributed by Free Software Foundation, Inc. *************** *** 19,23 **** /* gdevpjet.c */ ! /* H-P PaintJet driver for Ghostscript */ #include "gdevprn.h" #include "gdevpcl.h" --- 19,25 ---- /* gdevpjet.c */ ! /* H-P PaintJet, PaintJet XL, and DEC LJ250 driver for Ghostscript. */ ! /* Thanks to Rob Reiss (rob@moray.berkeley.edu) for the PaintJet XL */ ! /* modifications. */ #include "gdevprn.h" #include "gdevpcl.h" *************** *** 31,39 **** #define LINE_SIZE ((X_DPI * 85 / 10 + 63) / 64 * 8) ! /* The device descriptor */ private dev_proc_print_page(paintjet_print_page); private gx_device_procs paintjet_procs = prn_color_procs(gdev_prn_open, gdev_prn_output_page, gdev_prn_close, gdev_pcl_3bit_map_rgb_color, gdev_pcl_3bit_map_color_rgb); gx_device_printer gs_paintjet_device = prn_device(paintjet_procs, "paintjet", --- 33,51 ---- #define LINE_SIZE ((X_DPI * 85 / 10 + 63) / 64 * 8) ! /* The device descriptors */ ! private dev_proc_print_page(lj250_print_page); private dev_proc_print_page(paintjet_print_page); + private dev_proc_print_page(pjetxl_print_page); + private int pj_common_print_page(P4(gx_device_printer *, FILE *, int, const char *)); private gx_device_procs paintjet_procs = prn_color_procs(gdev_prn_open, gdev_prn_output_page, gdev_prn_close, gdev_pcl_3bit_map_rgb_color, gdev_pcl_3bit_map_color_rgb); + gx_device_printer gs_lj250_device = + prn_device(paintjet_procs, "lj250", + 85, /* width_10ths, 8.5" */ + 110, /* height_10ths, 11" */ + X_DPI, Y_DPI, + 0.25, 0, 0.25, 0, /* margins */ + 3, lj250_print_page); gx_device_printer gs_paintjet_device = prn_device(paintjet_procs, "paintjet", *************** *** 43,62 **** 0.25, 0, 0.25, 0, /* margins */ 3, paintjet_print_page); /* Forward references */ ! private int compress1_row(P3(byte _ss *, byte _ss *, byte _ss *)); /* ------ Internal routines ------ */ ! /* Send the page to the printer. Compress each scan line. */ private int paintjet_print_page(gx_device_printer *pdev, FILE *prn_stream) { #define DATA_SIZE (LINE_SIZE * 8) ! byte data[DATA_SIZE]; ! byte plane_data[LINE_SIZE * 3]; ! ! /* ends raster graphics to set raster graphics resolution */ ! fputs("\033*rB", prn_stream); /* set raster graphics resolution -- 90 or 180 dpi */ --- 55,124 ---- 0.25, 0, 0.25, 0, /* margins */ 3, paintjet_print_page); + private gx_device_procs pjetxl_procs = + prn_color_matrix_procs(gdev_prn_open, gdev_pcl_get_initial_matrix, + gdev_prn_output_page, gdev_prn_close, + gdev_pcl_3bit_map_rgb_color, gdev_pcl_3bit_map_color_rgb); + gx_device_printer gs_pjetxl_device = + prn_device(pjetxl_procs, "pjetxl", + 85, /* width_10ths, 8.5" */ + 110, /* height_10ths, 11" */ + X_DPI, Y_DPI, + 0.25, 0, 0, 0, /* margins */ + 3, pjetxl_print_page); /* Forward references */ ! private int compress1_row(P3(const byte *, const byte *, byte *)); /* ------ Internal routines ------ */ ! /* Send a page to the LJ250. We need to enter and exit */ ! /* the PaintJet emulation mode. */ ! private int ! lj250_print_page(gx_device_printer *pdev, FILE *prn_stream) ! { fputs("\033%8", prn_stream); /* Enter PCL emulation mode */ ! /* ends raster graphics to set raster graphics resolution */ ! fputs("\033*rB", prn_stream); ! /* Exit PCL emulation mode after printing */ ! return pj_common_print_page(pdev, prn_stream, 0, "\033*r0B\014\033%@"); ! } ! ! /* Send a page to the PaintJet. */ private int paintjet_print_page(gx_device_printer *pdev, FILE *prn_stream) + { /* ends raster graphics to set raster graphics resolution */ + fputs("\033*rB", prn_stream); + return pj_common_print_page(pdev, prn_stream, 0, "\033*r0B\014"); + } + + /* Send a page to the PaintJet XL. */ + private int + pjetxl_print_page(gx_device_printer *pdev, FILE *prn_stream) + { /* Initialize PaintJet XL for printing */ + fputs("\033E", prn_stream); + /* The XL has a different vertical origin, who knows why?? */ + return pj_common_print_page(pdev, prn_stream, -360, "\033*rC"); + } + + /* Send the page to the printer. Compress each scan line. */ + private int + pj_common_print_page(gx_device_printer *pdev, FILE *prn_stream, int y_origin, + const char *end_page) { #define DATA_SIZE (LINE_SIZE * 8) ! byte *data = ! (byte *)gs_malloc(DATA_SIZE, 1, ! "paintjet_print_page(data)"); ! byte *plane_data = ! (byte *)gs_malloc(LINE_SIZE * 3, 1, ! "paintjet_print_page(plane_data)"); ! if ( data == 0 || plane_data == 0 ) ! { if ( data ) ! gs_free((char *)data, DATA_SIZE, 1, ! "paintjet_print_page(data)"); ! if ( plane_data ) ! gs_free((char *)plane_data, LINE_SIZE * 3, 1, ! "paintjet_print_page(plane_data)"); ! return_error(gs_error_VMerror); ! } /* set raster graphics resolution -- 90 or 180 dpi */ *************** *** 70,74 **** /* move to top left of page */ ! fputs("\033&a0H\033&a0V", prn_stream); /* select data compression */ --- 132,136 ---- /* move to top left of page */ ! fprintf(prn_stream, "\033&a0H\033&a%dV", y_origin); /* select data compression */ *************** *** 83,87 **** int num_blank_lines = 0; for ( lnum = 0; lnum < pdev->height; lnum++ ) ! { byte _ss *end_data = data + line_size; gdev_prn_copy_scan_lines(pdev, lnum, (byte *)data, line_size); --- 145,149 ---- int num_blank_lines = 0; for ( lnum = 0; lnum < pdev->height; lnum++ ) ! { byte *end_data = data + line_size; gdev_prn_copy_scan_lines(pdev, lnum, (byte *)data, line_size); *************** *** 95,100 **** else { int i; ! byte _ss *odp; ! byte _ss *row; /* Pad with 0s to fill out the last */ --- 157,162 ---- else { int i; ! byte *odp; ! byte *row; /* Pad with 0s to fill out the last */ *************** *** 112,116 **** static ulong spr8[8] = spread3(8); static ulong spr2[8] = spread3(2); ! register byte _ss *dp = data + i; register ulong pword = (spr40[dp[0]] << 1) + --- 174,178 ---- static ulong spr8[8] = spread3(8); static ulong spr2[8] = spread3(2); ! register byte *dp = data + i; register ulong pword = (spr40[dp[0]] << 1) + *************** *** 150,158 **** } ! /* end raster graphics */ ! fputs("\033*r0B", prn_stream); ! /* eject page */ ! fputs("\014", prn_stream); return 0; --- 212,220 ---- } ! /* end the page */ ! fputs(end_page, prn_stream); ! gs_free((char *)data, DATA_SIZE, 1, "paintjet_print_page(data)"); ! gs_free((char *)plane_data, LINE_SIZE * 3, 1, "paintjet_print_page(plane_data)"); return 0; *************** *** 171,180 **** */ private int ! compress1_row(byte _ss *row, byte _ss *end_row, byte _ss *compressed) ! { register byte _ss *in = row; ! register byte _ss *out = compressed; while ( in < end_row ) { byte test = *in++; ! byte _ss *run = in; while ( in < end_row && *in == test ) in++; /* Note that in - run + 1 is the repetition count. */ --- 233,243 ---- */ private int ! compress1_row(const byte *row, const byte *end_row, ! byte *compressed) ! { register const byte *in = row; ! register byte *out = compressed; while ( in < end_row ) { byte test = *in++; ! const byte *run = in; while ( in < end_row && *in == test ) in++; /* Note that in - run + 1 is the repetition count. */ diff -rc2N gs241/gdevprn.c gs25/gdevprn.c *** gs241/gdevprn.c Thu Apr 9 04:04:22 1992 --- gs25/gdevprn.c Sat Aug 15 05:38:08 1992 *************** *** 30,37 **** private int open_scratch(char *fname, FILE **pfile) ! { *pfile = gp_open_scratch_file(SCRATCH_TEMPLATE, fname, "w+b"); if ( *pfile == NULL ) ! { eprintf1("could not open the scratch file %s.\n", fname); ! return -1; } return 0; --- 30,40 ---- private int open_scratch(char *fname, FILE **pfile) ! { char fmode[4]; ! strcpy(fmode, "w+"); ! strcat(fmode, gp_fmode_binary_suffix); ! *pfile = gp_open_scratch_file(SCRATCH_TEMPLATE, fname, fmode); if ( *pfile == NULL ) ! { eprintf1("Could not open the scratch file %s.\n", fname); ! return_error(gs_error_invalidfileaccess); } return 0; *************** *** 52,61 **** int gdev_prn_open(gx_device *pdev) ! { gx_device_memory *mdev = gdev_mem_device_for_bits(pdev->color_info.depth); ulong mem_space; byte *base; ! if ( mdev == 0 ) return -1; memset(ppdev->skip, 0, sizeof(ppdev->skip)); mem_space = gdev_mem_bitmap_size(pmemdev); if ( mem_space >= ppdev->max_bitmap || --- 55,69 ---- int gdev_prn_open(gx_device *pdev) ! { const gx_device_memory *mdev = gdev_mem_device_for_bits(pdev->color_info.depth); + gx_device_procs *pprocs = pdev->procs; ulong mem_space; byte *base; ! if ( mdev == 0 ) ! return_error(gs_error_rangecheck); memset(ppdev->skip, 0, sizeof(ppdev->skip)); + ppdev->orig_procs = pprocs; + ppdev->page_count = 0; + ppdev->file = ppdev->ccfile = ppdev->cbfile = NULL; mem_space = gdev_mem_bitmap_size(pmemdev); if ( mem_space >= ppdev->max_bitmap || *************** *** 65,68 **** --- 73,77 ---- { /* Buffer the image in a command list. */ uint space; + int code; for ( space = ppdev->use_buffer_space; ; ) { base = (byte *)gs_malloc(space, 1, *************** *** 69,85 **** "command list buffer"); if ( base != 0 ) break; ! if ( (space >>= 1) < PRN_BUFFER_SPACE ) ! return -1; /* no hope */ } ! ppdev->buffer_space = space; ! pcldev->mdev = *mdev; ! ppdev->buf = base; ! pcldev->data = base; pcldev->data_size = space; - if ( open_scratch(ppdev->ccfname, &ppdev->ccfile) < 0 ) - return -1; - if ( open_scratch(ppdev->cbfname, &ppdev->cbfile) < 0 ) - return -1; pcldev->target = pdev; pcldev->cfile = ppdev->ccfile; pcldev->bfile = ppdev->cbfile; --- 78,113 ---- "command list buffer"); if ( base != 0 ) break; ! if ( (space >>= 1) < PRN_MIN_BUFFER_SPACE ) ! return_error(gs_error_VMerror); /* no hope */ } ! open_c: pcldev->data = base; pcldev->data_size = space; pcldev->target = pdev; + pcldev->mdev = *mdev; + ppdev->buf = base; + ppdev->buffer_space = space; + /* Try opening the command list, to see if we allocated */ + /* enough buffer space. */ + code = (*gs_clist_device.procs->open_device)((gx_device *)pcldev); + if ( code < 0 ) + { /* If there wasn't enough room, and we haven't */ + /* already shrunk the buffer, try enlarging it. */ + if ( code == gs_error_limitcheck && + space >= ppdev->use_buffer_space + ) + { gs_free((char *)base, space, 1, + "command list buffer"); + space <<= 1; + base = (byte *)gs_malloc(space, 1, + "command list buffer"); + ppdev->buf = base; + if ( base != 0 ) goto open_c; + } + return code; + } + if ( (code = open_scratch(ppdev->ccfname, &ppdev->ccfile)) < 0 ) + return code; + if ( (code = open_scratch(ppdev->cbfname, &ppdev->cbfile)) < 0 ) + return code; pcldev->cfile = ppdev->ccfile; pcldev->bfile = ppdev->cbfile; *************** *** 98,116 **** /* Rendering operations come from the memory or clist device, */ /* non-rendering come from the printer device. */ ! { gx_device_procs *pprocs = pdev->procs; ! ppdev->orig_procs = pprocs; ! pdev->procs = &ppdev->mod_procs; #define copy_proc(p) ppdev->mod_procs.p = pprocs->p ! copy_proc(get_initial_matrix); ! copy_proc(output_page); ! copy_proc(close_device); ! copy_proc(map_rgb_color); ! copy_proc(map_color_rgb); ! copy_proc(get_props); ! copy_proc(put_props); #undef copy_proc - } - ppdev->page_count = 0; - ppdev->file = 0; return (*pdev->procs->open_device)(pdev); } --- 126,139 ---- /* Rendering operations come from the memory or clist device, */ /* non-rendering come from the printer device. */ ! pdev->procs = &ppdev->mod_procs; #define copy_proc(p) ppdev->mod_procs.p = pprocs->p ! copy_proc(get_initial_matrix); ! copy_proc(output_page); ! copy_proc(close_device); ! copy_proc(map_rgb_color); ! copy_proc(map_color_rgb); ! copy_proc(get_props); ! copy_proc(put_props); #undef copy_proc return (*pdev->procs->open_device)(pdev); } *************** *** 118,122 **** /* Added properties for printers */ ! private gs_prop_item props_prn[] = { prop_def("BufferSpace", prt_int), prop_def("MaxBitmap", prt_int), --- 141,145 ---- /* Added properties for printers */ ! private const gs_prop_item props_prn[] = { prop_def("BufferSpace", prt_int), prop_def("MaxBitmap", prt_int), *************** *** 144,153 **** gdev_prn_put_props(gx_device *pdev, gs_prop_item *plist, int count) { gs_prop_item *known[3]; props_extract(plist, count, props_prn, 3, known, 0); ! gx_default_put_props(pdev, plist, count); if ( known[0] != 0 ) { gs_prop_item *pi = known[0]; if ( pi->value.i < 10000 ) ! pi->status = pv_rangecheck; else ppdev->use_buffer_space = known[0]->value.i; --- 167,179 ---- gdev_prn_put_props(gx_device *pdev, gs_prop_item *plist, int count) { gs_prop_item *known[3]; + int code = 0; props_extract(plist, count, props_prn, 3, known, 0); ! code = gx_default_put_props(pdev, plist, count); ! if ( code < 0 ) return code; if ( known[0] != 0 ) { gs_prop_item *pi = known[0]; if ( pi->value.i < 10000 ) ! pi->status = pv_rangecheck, ! code = gs_error_rangecheck; else ppdev->use_buffer_space = known[0]->value.i; *************** *** 159,169 **** int size = pn->value.a.size; if ( size >= sizeof(ppdev->fname) ) ! pn->status = pv_limitcheck; else ! { memcpy(ppdev->fname, pn->value.a.p.s, size); ! pn->value.a.p.s[size] = 0; } } ! return 0; } --- 185,200 ---- int size = pn->value.a.size; if ( size >= sizeof(ppdev->fname) ) ! pn->status = pv_limitcheck, ! code = gs_error_limitcheck; else ! { /* Close the file if it's open. */ ! if ( ppdev->file != NULL && ppdev->file != stdout ) ! gp_close_printer(ppdev->file, ppdev->fname); ! ppdev->file = NULL; ! memcpy(ppdev->fname, pn->value.a.p.s, size); ! ppdev->fname[size] = 0; } } ! return code; } *************** *** 196,200 **** gdev_prn_close(gx_device *pdev) { if ( ppdev->ccfile != NULL ) ! { fclose(ppdev->ccfile); fclose(ppdev->cbfile); ppdev->ccfile = NULL; --- 227,231 ---- gdev_prn_close(gx_device *pdev) { if ( ppdev->ccfile != NULL ) ! { fclose(ppdev->ccfile); fclose(ppdev->cbfile); ppdev->ccfile = NULL; *************** *** 201,211 **** unlink(ppdev->ccfname); unlink(ppdev->cbfname); gs_free((char *)ppdev->buf, (uint)ppdev->buffer_space, 1, "command list buffer"); ! } if ( ppdev->file != NULL ) ! { gp_close_printer(ppdev->file, ppdev->fname); ppdev->file = NULL; ! } pdev->procs = ppdev->orig_procs; return 0; --- 232,251 ---- unlink(ppdev->ccfname); unlink(ppdev->cbfname); + } + if ( ppdev->buffer_space != 0 ) + { /* Free the buffer */ gs_free((char *)ppdev->buf, (uint)ppdev->buffer_space, 1, "command list buffer"); ! } ! else ! { /* Free the memory device bitmap */ ! gs_free(pmemdev->base, (uint)gdev_mem_bitmap_size(pmemdev), ! 1, "printer buffer"); ! } if ( ppdev->file != NULL ) ! { if ( ppdev->file != stdout ) ! gp_close_printer(ppdev->file, ppdev->fname); ppdev->file = NULL; ! } pdev->procs = ppdev->orig_procs; return 0; *************** *** 243,248 **** } if ( ppdev->file == NULL ) ! { ppdev->file = gp_open_printer(fname); ! if ( ppdev->file == NULL ) return -1; } return 0; --- 283,293 ---- } if ( ppdev->file == NULL ) ! { if ( !strcmp(fname, "-") ) ! ppdev->file = stdout; ! else ! { ppdev->file = gp_open_printer(fname); ! if ( ppdev->file == NULL ) ! return_error(gs_error_invalidfileaccess); ! } } return 0; *************** *** 268,272 **** int n; if ( swap ) /* swap the mask */ ! memswab(&last_mask, &last_mask, sizeof(last_mask)); for ( n = size; n >= line_size; n -= line_size, line_end += line_size --- 313,317 ---- int n; if ( swap ) /* swap the mask */ ! memswab4(&last_mask, &last_mask, sizeof(last_mask)); for ( n = size; n >= line_size; n -= line_size, line_end += line_size diff -rc2N gs241/gdevprn.h gs25/gdevprn.h *** gs241/gdevprn.h Sat Apr 11 05:33:54 1992 --- gs25/gdevprn.h Sun Aug 2 15:49:42 1992 *************** *** 23,27 **** #include "memory_.h" #include "string_.h" ! #include "gs.h" #include "gsmatrix.h" /* for gxdevice.h */ #include "gxdevice.h" --- 23,28 ---- #include "memory_.h" #include "string_.h" ! #include "gx.h" ! #include "gserrors.h" #include "gsmatrix.h" /* for gxdevice.h */ #include "gxdevice.h" *************** *** 42,45 **** --- 43,47 ---- # define PRN_BUFFER_SPACE 1000000L #endif + #define PRN_MIN_BUFFER_SPACE 10000 /* give up if less than this */ /* Define the declaration macro for print_page procedures. */ *************** *** 96,111 **** /* Macro for generating procedure table */ ! #define prn_procs(proc_open, proc_output_page, proc_close)\ ! prn_color_procs(proc_open, proc_output_page, proc_close,\ ! gdev_prn_map_rgb_color, gdev_prn_map_color_rgb) /* See gdev_prn_open for explanation of the NULLs below. */ ! #define prn_color_procs(proc_open, proc_output_page, proc_close, proc_map_rgb_color, proc_map_color_rgb) {\ ! proc_open,\ ! gx_default_get_initial_matrix,\ gx_default_sync_output,\ ! proc_output_page,\ ! proc_close,\ ! proc_map_rgb_color,\ ! proc_map_color_rgb,\ NULL, /* fill_rectangle */\ NULL, /* tile_rectangle */\ --- 98,117 ---- /* Macro for generating procedure table */ ! #define prn_procs(p_open, p_output_page, p_close)\ ! prn_matrix_procs(p_open, gx_default_get_initial_matrix, p_output_page, p_close) ! #define prn_matrix_procs(p_open,p_get_initial_matrix, p_output_page, p_close)\ ! prn_color_matrix_procs(p_open, p_get_initial_matrix, p_output_page, p_close,\ ! gdev_prn_map_rgb_color, gdev_prn_map_color_rgb) /* See gdev_prn_open for explanation of the NULLs below. */ ! #define prn_color_procs(p_open, p_output_page, p_close, p_map_rgb_color, p_map_color_rgb)\ ! prn_color_matrix_procs(p_open, gx_default_get_initial_matrix, p_output_page, p_close, p_map_rgb_color, p_map_color_rgb) ! #define prn_color_matrix_procs(p_open, p_get_initial_matrix, p_output_page, p_close, p_map_rgb_color, p_map_color_rgb) {\ ! p_open,\ ! p_get_initial_matrix,\ gx_default_sync_output,\ ! p_output_page,\ ! p_close,\ ! p_map_rgb_color,\ ! p_map_color_rgb,\ NULL, /* fill_rectangle */\ NULL, /* tile_rectangle */\ diff -rc2N gs241/gdevs3ga.c gs25/gdevs3ga.c *** gs241/gdevs3ga.c --- gs25/gdevs3ga.c Sat Aug 15 09:30:26 1992 *************** *** 0 **** --- 1,238 ---- + /* Copyright (C) 1992 Aladdin Enterprises. All rights reserved. + Distributed by Free Software Foundation, Inc. + + This file is part of Ghostscript. + + Ghostscript is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY. No author or distributor accepts responsibility + to anyone for the consequences of using it or for whether it serves any + particular purpose or works at all, unless he says so in writing. Refer + to the Ghostscript General Public License for full details. + + Everyone is granted permission to copy, modify and redistribute + Ghostscript, but only under the conditions described in the Ghostscript + General Public License. A copy of this license is supposed to have been + given to you along with Ghostscript so you can know your rights and + responsibilities. It should be in a file named COPYING. Among other + things, the copyright notice and this notice must be preserved on all + copies. */ + + /* gdevs3ga.c */ + /* S3 86C911 driver for Ghostscript */ + #include "gx.h" + #include "gserrors.h" + #include "gxdevice.h" + #include "gdevpcfb.h" + #include "gdevsvga.h" + + /* Shared routines from gdevsvga.c */ + extern int vesa_get_mode(P0()); + extern void vesa_set_mode(P1(int)); + + /* Macro for casting gx_device argument */ + #define fb_dev ((gx_device_svga *)dev) + + /* ------ The S3 86C911 device ------ */ + + private dev_proc_open_device(s3_open); + private dev_proc_fill_rectangle(s3_fill_rectangle); + private dev_proc_copy_mono(s3_copy_mono); + private gx_device_procs s3_procs = { + s3_open, + gx_default_get_initial_matrix, + gx_default_sync_output, + gx_default_output_page, + svga_close, + svga_map_rgb_color, + svga_map_color_rgb, + s3_fill_rectangle, + gx_default_tile_rectangle, + s3_copy_mono, + svga_copy_color, /****** DOESN'T WORK ******/ + gx_default_draw_line, + svga_get_bits, /****** DOESN'T WORK ******/ + gx_default_get_props, + gx_default_put_props + }; + gx_device_svga gs_s3vga_device = + svga_device(s3_procs, "s3vga", vesa_get_mode, vesa_set_mode, NULL); + + /* Keep track of the character bitmap cache in off-screen memory. */ + #define log2_cell_width 5 + #define cell_width (1 << log2_cell_width) + #define cache_x_bits (log2_cache_width_bits - log2_cell_width) + #define log2_cell_height 5 + #define cell_height (1 << log2_cell_height) + #define cache_y_bits (log2_cache_height - log2_cell_height) + #define log2_cache_width_bits 10 + #define log2_cache_width_bytes (log2_cache_width_bits - 3) + #define log2_cache_height 8 + #define log2_cache_capacity (cache_x_bits + cache_y_bits) + #define cache_capacity (1 << log2_cache_capacity) + private gx_bitmap_id cache_ids[cache_capacity]; + + /* Define additional registers and I/O addresses. */ + #define crtc_addr 0x3d4 /* (color) */ + #define crt_lock 0x35 + #define crt_s3_lock1 0x38 + #define crt_s3_lock2 0x39 + #define s3_y_pos 0x82e8 + #define s3_x_pos 0x86e8 + #define s3_y_dest 0x8ae8 + #define s3_x_dest 0x8ee8 + #define s3_width 0x96e8 + #define s3_status 0x9ae8 /* read only */ + #define s3_command 0x9ae8 /* write only */ + #define s3_back_color 0xa2e8 + #define s3_fore_color 0xa6e8 + #define s3_write_mask 0xaae8 + #define s3_read_mask 0xaee8 + #define s3_back_mix 0xb6e8 + #define s3_fore_mix 0xbae8 + #define s3_height 0xbee8 + #define s3_mf_control 0xbee8 + # define mf_data_ones 0xa000 + # define mf_data_cpu 0xa080 + # define mf_data_display 0xa0c0 + #define s3_pixel_data 0xe2e8 + /* Wait for the command FIFO to empty. */ + #define s3_wait_fifo()\ + while ( inport(s3_status) & 0xff ) + /* Load the parameters for a rectangle operation. */ + #define out_s3_rect(x, y, w, h)\ + (outport(s3_x_pos, x), outport(s3_y_pos, y),\ + outport(s3_width, (w) - 1), outport(s3_height, (h) - 1)) + + private int + s3_open(gx_device *dev) + { static const mode_info mode_table[] = { + { 640, 480, 0x201 }, + { 800, 600, 0x203 }, + { 1024, 768, 0x205 }, + { -1, -1, -1 } + }; + int code = svga_find_mode(dev, mode_table); + if ( code < 0 ) return_error(gs_error_rangecheck); + /* The enhanced modes all use a 1024-pixel raster. */ + fb_dev->raster = 1024; + code = svga_open(dev); + if ( code < 0 ) return code; + /* Clear the cache */ + { int i; + for ( i = 0; i < cache_capacity; i++ ) + cache_ids[i] = gx_no_bitmap_id; + } + return 0; + } + + /* Fill a rectangle. */ + int + s3_fill_rectangle(gx_device *dev, int x, int y, int w, int h, + gx_color_index color) + { validate_rect(); + s3_wait_fifo(); + outport(s3_fore_mix, 0x27); + outport(s3_fore_color, (int)color); + outport(s3_mf_control, mf_data_ones); + out_s3_rect(x, y, w, h); + outport(s3_command, 0x40b3); + return 0; + } + + /* Copy a monochrome bitmap. The colors are given explicitly. */ + /* Color = gx_no_color_index means transparent (no effect on the image). */ + private int + s3_copy_mono(gx_device *dev, + const byte *base, int sourcex, int raster, gx_bitmap_id id, + int x, int y, int w, int h, gx_color_index czero, gx_color_index cone) + { int i, j; + const int sbit = sourcex & 7; + const byte *sptr = base + (sourcex >> 3); + const int run = (sbit + w + 7) >> 3; + const byte lmask = 0xff >> sbit; + byte lmerge = 0; + int cache_index, cache_x, cache_y; + validate_rect(); + /* See whether the cache is applicable. */ + if ( id != gx_no_bitmap_id && w <= cell_width - 7 && + h <= cell_height + ) + { cache_index = (int)(id & (cache_capacity - 1)); + cache_x = ((cache_index & ((1 << cache_x_bits) - 1)) << + log2_cell_width) + 7; + cache_y = ((cache_index >> cache_x_bits) << + log2_cell_height) + 768; + if ( cache_ids[cache_index] != id ) + { cache_ids[cache_index] = id; + /* Copy the bitmap to the cache. */ + s3_wait_fifo(); + out_s3_rect(cache_x - sbit, cache_y, w + sbit, h); + outport(s3_fore_mix, 0x22); /* 1s */ + outport(s3_back_mix, 0x01); /* 0s */ + outport(s3_mf_control, mf_data_cpu); + outport(s3_command, 0x41b3); + { const int skip = raster - run; + for ( i = h; i > 0; i--, sptr += skip ) + for ( j = run; j > 0; j--, sptr++ ) + outportb(s3_pixel_data, *sptr); + } + } + s3_wait_fifo(); + } + else + { cache_index = -1; + if ( lmask != 0xff ) + { /* The hardware won't do the masking for us. */ + if ( czero != gx_no_color_index ) + { if ( cone != gx_no_color_index ) + { s3_fill_rectangle(dev, x, y, w, h, czero); + czero = gx_no_color_index; + } + else + { lmerge = ~lmask; + } + } + } + s3_wait_fifo(); + out_s3_rect(x - sbit, y, w + sbit, h); + } + /* Load the colors for the real transfer. */ + if ( cone != gx_no_color_index ) + { outport(s3_fore_mix, 0x27); + outport(s3_fore_color, (int)cone); + } + else + outport(s3_fore_mix, 0x63); + if ( czero != gx_no_color_index ) + { outport(s3_back_mix, 0x07); + outport(s3_back_color, (int)czero); + } + else + outport(s3_back_mix, 0x63); + s3_wait_fifo(); + if ( cache_index < 0 ) /* direct transfer */ + { outport(s3_mf_control, mf_data_cpu); + outport(s3_command, 0x41b3); + if ( run == 1 && !lmerge ) /* special case for chars */ + { for ( i = h; i > 0; i--, sptr += raster ) + outportb(s3_pixel_data, *sptr & lmask); + } + else + { const int skip = raster - run; + for ( i = h; i > 0; i--, sptr += skip ) + { outportb(s3_pixel_data, (*sptr++ & lmask) | lmerge); + for ( j = run; j > 1; j--, sptr++ ) + outportb(s3_pixel_data, *sptr); + } + } + } + else + { /* Copy the character from the cache to the screen. */ + out_s3_rect(cache_x, cache_y, w, h); + outport(s3_x_dest, x); + outport(s3_y_dest, y); + outport(s3_mf_control, mf_data_display); + outport(s3_command, 0xc0b3); + } + return 0; + } diff -rc2N gs241/gdevsun.c gs25/gdevsun.c *** gs241/gdevsun.c Mon Apr 6 13:59:08 1992 --- gs25/gdevsun.c Thu Jul 9 12:44:40 1992 *************** *** 496,502 **** xdev->ncols++; - - if (xdev->ncols == ALL_COLS) - return i; } --- 496,499 ---- *************** *** 564,570 **** int sun_copy_mono(register gx_device *dev, ! byte *base, int sourcex, int raster, gx_bitmap_id id, int x, int y, int w, int h, gx_color_index zero, gx_color_index one) { register int i; int nbytes = h * raster; --- 561,572 ---- int sun_copy_mono(register gx_device *dev, ! const byte *base, int sourcex, int raster, gx_bitmap_id id, int x, int y, int w, int h, gx_color_index zero, gx_color_index one) { + /* We define a non-const pointer to the data so we can invert it or */ + /* byte-swap it in place temporarily (we restore it at the end). */ + /* Yes, this is a bad and wicked thing to do! */ + #define non_const_base ((byte *)base) + register int i; int nbytes = h * raster; *************** *** 586,590 **** #if !arch_is_big_endian /* Reverse the bit order in each byte. */ ! for ( i = 0; i < nbytes; i++ ) base[i] = reverse_bits[base[i]]; #endif pw_batch_on(xdev->pw); --- 588,593 ---- #if !arch_is_big_endian /* Reverse the bit order in each byte. */ ! for ( i = 0; i < nbytes; i++ ) ! non_const_base[i] = reverse_bits[base[i]]; #endif pw_batch_on(xdev->pw); *************** *** 596,600 **** } if (zero != gx_no_color_index) ! { for (i = 0; i < nbytes; i++) base[i] = ~base[i]; pw_stencil(xdev->pw, x, y, w, h, PIX_SRC | PIX_COLOR(zero), &(xdev->pr), --- 599,604 ---- } if (zero != gx_no_color_index) ! { for (i = 0; i < nbytes; i++) ! non_const_base[i] = ~base[i]; pw_stencil(xdev->pw, x, y, w, h, PIX_SRC | PIX_COLOR(zero), &(xdev->pr), *************** *** 601,605 **** ((int)base & 1) ? sourcex + 8 : sourcex, 0, (Pixrect *)0, 0, 0); ! for (i = 0; i < nbytes; i++) base[i] = ~base[i]; } pw_batch_off(xdev->pw); --- 605,610 ---- ((int)base & 1) ? sourcex + 8 : sourcex, 0, (Pixrect *)0, 0, 0); ! for (i = 0; i < nbytes; i++) ! non_const_base[i] = ~base[i]; } pw_batch_off(xdev->pw); *************** *** 606,610 **** #if !arch_is_big_endian /* Reverse the bits back again. */ ! for ( i = 0; i < nbytes; i++ ) base[i] = reverse_bits[base[i]]; #endif (void) notify_dispatch(); --- 611,616 ---- #if !arch_is_big_endian /* Reverse the bits back again. */ ! for ( i = 0; i < nbytes; i++ ) ! non_const_base[i] = reverse_bits[base[i]]; #endif (void) notify_dispatch(); *************** *** 615,619 **** int sun_copy_color(register gx_device *dev, ! byte *base, int sourcex, int raster, gx_bitmap_id id, int x, int y, int w, int h) { --- 621,625 ---- int sun_copy_color(register gx_device *dev, ! const byte *base, int sourcex, int raster, gx_bitmap_id id, int x, int y, int w, int h) { diff -rc2N gs241/gdevsvga.c gs25/gdevsvga.c *** gs241/gdevsvga.c Wed Apr 15 15:22:00 1992 --- gs25/gdevsvga.c Sat Aug 15 09:42:30 1992 *************** *** 1,3 **** ! /* Copyright (C) 1991 Aladdin Enterprises. All rights reserved. Distributed by Free Software Foundation, Inc. --- 1,3 ---- ! /* Copyright (C) 1991, 1992 Aladdin Enterprises. All rights reserved. Distributed by Free Software Foundation, Inc. *************** *** 23,78 **** typedef union REGS registers; #include "memory_.h" ! #include "gs.h" #include "gxdevice.h" - #ifndef USE_ASM - # define USE_ASM 0 /* don't use assembly language */ - #endif - - /* Define the short (integer) version of "transparent" color. */ - /* ****** Depends on gx_no_color_index being all 1's. ******/ - #define no_color ((int)gx_no_color_index) - - /* Procedures */ - - /* See gxdevice.h for the definitions of the procedures. */ - - private dev_proc_close_device(svga_close); - private dev_proc_map_rgb_color(svga_map_rgb_color); - private dev_proc_map_color_rgb(svga_map_color_rgb); - private dev_proc_fill_rectangle(svga_fill_rectangle); - private dev_proc_copy_mono(svga_copy_mono); - private dev_proc_copy_color(svga_copy_color); - private dev_proc_get_bits(svga_get_bits); - - /* Type for frame buffer pointers. */ - /*** Intimately tied to the 80x86 (x<2) addressing architecture. ***/ - typedef byte far *fb_ptr; - - /* The device descriptor */ - typedef struct gx_device_svga_s gx_device_svga; - struct gx_device_svga_s { - gx_device_common; - int (*get_mode)(P0()); - void (*set_mode)(P1(int)); - void (*set_page)(P3(gx_device_svga *, int, int)); - uint raster; /* frame buffer bytes per line */ - int page; /* current page */ - int wnum_read, wnum_write; /* window #s for read vs. write */ - /* Following are device-specific. */ - union { - struct { - void (*bios_set_page)(P2(int, int)); /* set-page function */ - } vesa; - struct { - int select_reg; /* page-select register */ - } atiw; - struct { - int et_model; /* 4 for ET4000, */ - /* 3 for ET3000 */ - } tseng; - } info; - }; - /* The color map for dynamically assignable colors. */ #define first_color_index 64 --- 23,32 ---- typedef union REGS registers; #include "memory_.h" ! #include "gx.h" ! #include "gserrors.h" #include "gxdevice.h" + #include "gdevpcfb.h" + #include "gdevsvga.h" /* The color map for dynamically assignable colors. */ #define first_color_index 64 *************** *** 93,111 **** } - /* The initial parameters map an appropriate fraction of */ - /* the screen to an 8.5" x 11" coordinate space. */ - /* This may or may not be what is desired! */ - #define svga_device(procs, name, get_mode, set_mode, set_page) {\ - sizeof(gx_device_svga),\ - &procs,\ - name,\ - 640, 480, /* screen size */\ - 480 / 11.0, 480 / 11.0, /* resolution */\ - no_margins,\ - dci_color(8, 31, 4),\ - 0, /* not opened yet */\ - get_mode, set_mode, set_page\ - } - /* Save the controller mode */ private int svga_save_mode = -1; --- 47,50 ---- *************** *** 113,119 **** /* Macro for validating rectangle parameters x and w. */ /* set_pixel_ptr implicitly validates y and h. */ ! #define validate_rect()\ if ( w <= 0 ) return 0;\ ! if ( x < 0 || x + w > dev->width ) return -1 /* ------ Internal routines ------ */ --- 52,58 ---- /* Macro for validating rectangle parameters x and w. */ /* set_pixel_ptr implicitly validates y and h. */ ! #define validate_rect_x()\ if ( w <= 0 ) return 0;\ ! if ( x < 0 || x + w > dev->width ) return_error(gs_error_rangecheck) /* ------ Internal routines ------ */ *************** *** 126,130 **** { ulong index = (ulong)(y) * fbdev->raster + (uint)(x);\ if ( (uint)(index >> 16) != fbdev->page )\ ! { if ( y < 0 || y >= fbdev->height ) return -1;\ (*fbdev->set_page)(fbdev, (fbdev->page = index >> 16), wnum);\ }\ --- 65,69 ---- { ulong index = (ulong)(y) * fbdev->raster + (uint)(x);\ if ( (uint)(index >> 16) != fbdev->page )\ ! { if ( y < 0 || y >= fbdev->height ) return_error(gs_error_rangecheck);\ (*fbdev->set_page)(fbdev, (fbdev->page = index >> 16), wnum);\ }\ *************** *** 136,156 **** set_pixel_ptr(ptr, fbdev, x, y, fbdev->wnum_read) - /* Table structure for looking up graphics modes. */ - typedef struct { - int width, height; /* "key" */ - int mode; /* "value" */ - } mode_info; - /* Find the graphics mode for a desired width and height. */ ! /* Return the graphics mode or -1. */ ! private int ! svga_find_mode(gx_device *dev, mode_info _ds *mip) ! { for ( ; mip->mode >= 0; mip++ ) ! { if ( mip->width == fb_dev->width && ! mip->height == fb_dev->height ) ! return mip->mode; ! } ! return -1; } --- 75,94 ---- set_pixel_ptr(ptr, fbdev, x, y, fbdev->wnum_read) /* Find the graphics mode for a desired width and height. */ ! /* Set the mode in the device structure and return 0, */ ! /* or return an error code. */ ! int ! svga_find_mode(gx_device *dev, const mode_info _ds *mip) ! { fb_dev->raster = fb_dev->width; ! for ( ; mip->mode >= 0; mip++ ) ! { if ( mip->width >= fb_dev->width && ! mip->height >= fb_dev->height ) ! { fb_dev->mode = mip; ! gx_device_adjust_resolution(dev, mip->width, mip->height); ! return 0; ! } ! } ! return_error(gs_error_rangecheck); } *************** *** 165,172 **** /* Initialize the device structure and the DACs. */ ! private int ! svga_open(gx_device *dev, int mode) ! { fb_dev->raster = fb_dev->width; ! fb_dev->x_pixels_per_inch = fb_dev->y_pixels_per_inch = fb_dev->height / 11.0; --- 103,109 ---- /* Initialize the device structure and the DACs. */ ! int ! svga_open(gx_device *dev) ! { fb_dev->x_pixels_per_inch = fb_dev->y_pixels_per_inch = fb_dev->height / 11.0; *************** *** 174,178 **** if ( svga_save_mode < 0 ) svga_save_mode = (*fb_dev->get_mode)(); ! (*fb_dev->set_mode)(mode); /* Load the color DAC. */ svga_dac_set_write_index(0); --- 111,115 ---- if ( svga_save_mode < 0 ) svga_save_mode = (*fb_dev->get_mode)(); ! (*fb_dev->set_mode)(fb_dev->mode->mode); /* Load the color DAC. */ svga_dac_set_write_index(0); *************** *** 179,183 **** { int c; for ( c = 0; c < 64; c++ ) ! { static byte c2[10] = { 0, 42, 0, 0, 0, 0, 0, 0, 21, 63 }; svga_dac_write(c2[(c >> 2) & 9], c2[(c >> 1) & 9], --- 116,120 ---- { int c; for ( c = 0; c < 64; c++ ) ! { static const byte c2[10] = { 0, 42, 0, 0, 0, 0, 0, 0, 21, 63 }; svga_dac_write(c2[(c >> 2) & 9], c2[(c >> 1) & 9], *************** *** 192,196 **** /* Close the device; reinitialize the display for text mode. */ ! private int svga_close(gx_device *dev) { if ( svga_save_mode >= 0 ) --- 129,133 ---- /* Close the device; reinitialize the display for text mode. */ ! int svga_close(gx_device *dev) { if ( svga_save_mode >= 0 ) *************** *** 204,208 **** /* for compatibility with the older display modes: */ /* these are indexed as 0.0.R0.G0.B0.R1.G1.B1. */ ! private gx_color_index svga_map_rgb_color(gx_device *dev, ushort r, ushort g, ushort b) { --- 141,145 ---- /* for compatibility with the older display modes: */ /* these are indexed as 0.0.R0.G0.B0.R1.G1.B1. */ ! gx_color_index svga_map_rgb_color(gx_device *dev, ushort r, ushort g, ushort b) { *************** *** 209,213 **** #define cv_bits(v,n) (v >> (gx_color_value_bits - n)) ushort r5 = cv_bits(r, 5), g5 = cv_bits(g, 5), b5 = cv_bits(b, 5); ! static byte cube_bits[32] = { 0, 128, 128, 128, 128, 128, 128, 128, 128, 128, 8, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, --- 146,150 ---- #define cv_bits(v,n) (v >> (gx_color_value_bits - n)) ushort r5 = cv_bits(r, 5), g5 = cv_bits(g, 5), b5 = cv_bits(b, 5); ! static const byte cube_bits[32] = { 0, 128, 128, 128, 128, 128, 128, 128, 128, 128, 8, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, *************** *** 244,248 **** /* This routine must invert the transformation of the one above. */ /* Since this is practically never used, we just read the DAC. */ ! private int svga_map_color_rgb(gx_device *dev, gx_color_index color, ushort prgb[3]) { uint cval; --- 181,185 ---- /* This routine must invert the transformation of the one above. */ /* Since this is practically never used, we just read the DAC. */ ! int svga_map_color_rgb(gx_device *dev, gx_color_index color, ushort prgb[3]) { uint cval; *************** *** 260,266 **** /* Copy a monochrome bitmap. The colors are given explicitly. */ /* Color = gx_no_color_index means transparent (no effect on the image). */ ! private int svga_copy_mono(gx_device *dev, ! byte *base, int sourcex, int raster, gx_bitmap_id id, int x, int y, int w, int h, gx_color_index czero, gx_color_index cone) { register int xi; --- 197,203 ---- /* Copy a monochrome bitmap. The colors are given explicitly. */ /* Color = gx_no_color_index means transparent (no effect on the image). */ ! int svga_copy_mono(gx_device *dev, ! const byte *base, int sourcex, int raster, gx_bitmap_id id, int x, int y, int w, int h, gx_color_index czero, gx_color_index cone) { register int xi; *************** *** 268,278 **** int yi; fb_ptr ptr = (fb_ptr)0; ! byte *srow = base + (sourcex >> 3); uint imask = 0x80 >> (sourcex & 7); ! validate_rect(); #define izero (int)czero #define ione (int)cone for ( yi = 0; yi < h; yi++ ) ! { byte *sptr = srow; uint bits = *sptr; register uint mask = imask; --- 205,215 ---- int yi; fb_ptr ptr = (fb_ptr)0; ! const byte *srow = base + (sourcex >> 3); uint imask = 0x80 >> (sourcex & 7); ! validate_rect_x(); #define izero (int)czero #define ione (int)cone for ( yi = 0; yi < h; yi++ ) ! { const byte *sptr = srow; uint bits = *sptr; register uint mask = imask; *************** *** 301,313 **** /* Copy a color pixelmap. This is just like a bitmap, */ /* except that each pixel takes 8 bits instead of 1. */ ! private int svga_copy_color(gx_device *dev, ! byte *base, int sourcex, int raster, gx_bitmap_id id, int x, int y, int w, int h) { int xi, yi; int skip = raster - w; ! byte *sptr = base + sourcex; fb_ptr ptr; ! validate_rect(); for ( yi = y; yi - y < h; yi++ ) { ptr = 0; --- 238,250 ---- /* Copy a color pixelmap. This is just like a bitmap, */ /* except that each pixel takes 8 bits instead of 1. */ ! int svga_copy_color(gx_device *dev, ! const byte *base, int sourcex, int raster, gx_bitmap_id id, int x, int y, int w, int h) { int xi, yi; int skip = raster - w; ! const byte *sptr = base + sourcex; fb_ptr ptr; ! validate_rect_x(); for ( yi = y; yi - y < h; yi++ ) { ptr = 0; *************** *** 323,327 **** /* Fill a rectangle. */ ! private int svga_fill_rectangle(gx_device *dev, int x, int y, int w, int h, gx_color_index color) --- 260,264 ---- /* Fill a rectangle. */ ! int svga_fill_rectangle(gx_device *dev, int x, int y, int w, int h, gx_color_index color) *************** *** 416,421 **** private dev_proc_open_device(vesa_open); private gx_device_procs vesa_procs = svga_procs(vesa_open); ! private int vesa_get_mode(P0()); ! private void vesa_set_mode(P1(int)); private void vesa_set_page(P3(gx_device_svga *, int, int)); gx_device_svga gs_vesa_device = --- 353,358 ---- private dev_proc_open_device(vesa_open); private gx_device_procs vesa_procs = svga_procs(vesa_open); ! int vesa_get_mode(P0()); ! void vesa_set_mode(P1(int)); private void vesa_set_page(P3(gx_device_svga *, int, int)); gx_device_svga gs_vesa_device = *************** *** 422,427 **** svga_device(vesa_procs, "vesa", vesa_get_mode, vesa_set_mode, vesa_set_page); ! /* Define the structure for information returned by the BIOS. */ #define bits_include(a, m) !(~(a) & (m)) typedef enum { m_supported = 1, --- 359,373 ---- svga_device(vesa_procs, "vesa", vesa_get_mode, vesa_set_mode, vesa_set_page); ! /* Define the structures for information returned by the BIOS. */ #define bits_include(a, m) !(~(a) & (m)) + /* Information about the BIOS capabilities. */ + typedef struct { + byte vesa_signature[4]; /* "VESA" */ + ushort vesa_version; + char *product_info; /* product name string */ + byte capabilities[4]; /* (undefined) */ + ushort *mode_list; /* supported video modes, -1 ends */ + } vga_bios_info; + /* Information about an individual VESA mode. */ typedef enum { m_supported = 1, *************** *** 453,460 **** byte memory_model; byte bank_size; } vesa_info; /* Read the device mode */ ! private int vesa_get_mode() { registers regs; --- 399,408 ---- byte memory_model; byte bank_size; + /* Padding to 256 bytes */ + byte _padding[256-29]; } vesa_info; /* Read the device mode */ ! int vesa_get_mode() { registers regs; *************** *** 466,470 **** /* Set the device mode */ ! private void vesa_set_mode(int mode) { registers regs; --- 414,418 ---- /* Set the device mode */ ! void vesa_set_mode(int mode) { registers regs; *************** *** 483,489 **** regs.h.al = 0x01; regs.rshort.cx = mode; - regs.rshort.di = PTR_OFF(info); segread(&sregs); sregs.es = sregs.ss; int86x(0x10, ®s, ®s, &sregs); #ifdef DEBUG --- 431,437 ---- regs.h.al = 0x01; regs.rshort.cx = mode; segread(&sregs); sregs.es = sregs.ss; + regs.rshort.di = PTR_OFF(info); int86x(0x10, ®s, ®s, &sregs); #ifdef DEBUG *************** *** 502,560 **** /* Initialize the graphics mode. */ private int ! vesa_open(gx_device *dev) { /* Select the proper video mode */ ! { vesa_info info; ! static mode_info mode_table[6] = { ! { 640, 400, 0x100 }, ! { 640, 480, 0x101 }, ! { 800, 600, 0x103 }, ! { 1024, 768, 0x105 }, ! { 1280, 1024, 0x107 }, ! { -1, -1, -1 } ! }; ! mode_info _ds *mip; ! for ( mip = mode_table; mip->mode >= 0; mip++ ) ! { if ( mip->width == fb_dev->width && ! mip->height == fb_dev->height && ! vesa_get_info(mip->mode, &info) >= 0 && ! bits_include(info.mode_attributes, ! m_supported | m_graphics) && ! info.win_granularity == 64 && ! info.win_size == 64 && ! bits_include(info.win_a_attributes, ! w_supported) && ! info.win_a_segment == regen ) ! { /* Make sure we can both read & write. */ ! /* Initialize for the default case. */ ! fb_dev->wnum_read = 0; ! fb_dev->wnum_write = 0; ! if ( bits_include(info.win_a_attributes, w_readable | w_writable) ! ) ! break; ! else if ( info.win_b_segment == regen && ! bits_include(info.win_b_attributes, ! w_supported) && ! bits_include(info.win_a_attributes | ! info.win_b_attributes, ! w_readable | w_writable) ) ! { /* Two superimposed windows. */ ! if ( !bits_include(info.win_a_attributes, ! w_writable) ! ) ! fb_dev->wnum_write = 1; ! else ! fb_dev->wnum_read = 1; ! } ! break; } } - if ( mip->mode < 0 ) return -1; /* mode not available */ - fb_dev->info.vesa.bios_set_page = info.win_func_ptr; - return svga_open(dev, mip->mode); } } --- 450,519 ---- /* Initialize the graphics mode. */ + /* Shared routine to look up a VESA-compatible BIOS mode. */ private int ! vesa_find_mode(gx_device *dev, const mode_info _ds *mode_table) { /* Select the proper video mode */ ! vesa_info info; ! const mode_info _ds *mip; ! for ( mip = mode_table; mip->mode >= 0; mip++ ) ! { if ( mip->width >= fb_dev->width && ! mip->height >= fb_dev->height && ! vesa_get_info(mip->mode, &info) >= 0 && ! bits_include(info.mode_attributes, ! m_supported | m_graphics) && ! info.win_granularity == 64 && ! info.win_size == 64 && ! bits_include(info.win_a_attributes, ! w_supported) && ! info.win_a_segment == regen ! ) ! { /* Make sure we can both read & write. */ ! /* Initialize for the default case. */ ! fb_dev->wnum_read = 0; ! fb_dev->wnum_write = 0; ! if ( bits_include(info.win_a_attributes, ! w_readable | w_writable) ) ! break; ! else if ( info.win_b_segment == regen && ! bits_include(info.win_b_attributes, ! w_supported) && ! bits_include(info.win_a_attributes | ! info.win_b_attributes, w_readable | w_writable) ! ) ! { /* Two superimposed windows. */ ! if ( !bits_include(info.win_a_attributes, ! w_writable) ) ! fb_dev->wnum_write = 1; ! else ! fb_dev->wnum_read = 1; } + break; } } + if ( mip->mode < 0 ) + return_error(gs_error_rangecheck); /* mode not available */ + fb_dev->mode = mip; + gx_device_adjust_resolution(dev, mip->width, mip->height); + fb_dev->info.vesa.bios_set_page = info.win_func_ptr; + /* Reset the raster per the VESA info. */ + fb_dev->raster = info.bytes_per_line; + return 0; + } + private int + vesa_open(gx_device *dev) + { static const mode_info mode_table[] = { + { 640, 400, 0x100 }, + { 640, 480, 0x101 }, + { 800, 600, 0x103 }, + { 1024, 768, 0x105 }, + { 1280, 1024, 0x107 }, + { -1, -1, -1 } + }; + int code = vesa_find_mode(dev, mode_table); + if ( code < 0 ) return code; + return svga_open(dev); } *************** *** 610,614 **** atiw_open(gx_device *dev) { /* Select the proper video mode */ ! { static mode_info mode_table[4] = { { 640, 400, 0x61 }, { 640, 480, 0x62 }, --- 569,573 ---- atiw_open(gx_device *dev) { /* Select the proper video mode */ ! { static const mode_info mode_table[] = { { 640, 400, 0x61 }, { 640, 480, 0x62 }, *************** *** 616,623 **** { -1, -1, -1 } }; ! int mode = svga_find_mode(dev, mode_table); ! if ( mode < 0 ) return -1; /* mode not available */ fb_dev->info.atiw.select_reg = *(int *)MK_PTR(0xc000, 0x10); ! return svga_open(dev, mode); } } --- 575,582 ---- { -1, -1, -1 } }; ! int code = svga_find_mode(dev, mode_table); ! if ( code < 0 ) return code; /* mode not available */ fb_dev->info.atiw.select_reg = *(int *)MK_PTR(0xc000, 0x10); ! return svga_open(dev); } } *************** *** 636,639 **** --- 595,638 ---- } + /* ------ The Trident device ------ */ + + private dev_proc_open_device(tvga_open); + private gx_device_procs tvga_procs = svga_procs(tvga_open); + /* We can use the tseng_get/set_mode procedures. */ + private void tvga_set_page(P3(gx_device_svga *, int, int)); + gx_device_svga gs_tvga_device = + svga_device(tvga_procs, "tvga", atiw_get_mode, atiw_set_mode, tvga_set_page); + + /* Initialize the graphics mode. */ + private int + tvga_open(gx_device *dev) + { fb_dev->wnum_read = 1; + fb_dev->wnum_write = 0; + /* Select the proper video mode */ + { static const mode_info mode_table[] = { + { 640, 400, 0x5c }, + { 640, 480, 0x5d }, + { 800, 600, 0x5e }, + { 1024, 768, 0x62 }, + { -1, -1, -1 } + }; + int code = svga_find_mode(dev, mode_table); + if ( code < 0 ) return code; /* mode not available */ + return svga_open(dev); + } + } + + /* Set the current display page. */ + private void + tvga_set_page(gx_device_svga *dev, int pn, int wnum) + { + /* new mode */ + outportb(0x3c4, 0x0b); + inportb(0x3c4); + + outportb(0x3c4, 0x0e); + outportb(0x3c5, pn ^ 2); + } + /* ------ The Tseng Labs ET3000/4000 device ------ */ *************** *** 651,655 **** fb_dev->wnum_write = 0; /* Select the proper video mode */ ! { static mode_info mode_table[5] = { { 640, 350, 0x2d }, { 640, 480, 0x2e }, --- 650,654 ---- fb_dev->wnum_write = 0; /* Select the proper video mode */ ! { static const mode_info mode_table[] = { { 640, 350, 0x2d }, { 640, 480, 0x2e }, *************** *** 658,664 **** { -1, -1, -1 } }; ! int mode = svga_find_mode(dev, mode_table); fb_ptr p0 = (fb_ptr)MK_PTR(regen, 0); ! if ( mode < 0 ) return -1; /* mode not available */ /* Figure out whether we have an ET3000 or an ET4000 */ /* by playing with the segment register. */ --- 657,663 ---- { -1, -1, -1 } }; ! int code = svga_find_mode(dev, mode_table); fb_ptr p0 = (fb_ptr)MK_PTR(regen, 0); ! if ( code < 0 ) return code; /* mode not available */ /* Figure out whether we have an ET3000 or an ET4000 */ /* by playing with the segment register. */ *************** *** 670,674 **** /* read page 0 if ET3000, */ /* page 4 if ET4000 */ ! return svga_open(dev, mode); } } --- 669,673 ---- /* read page 0 if ET3000, */ /* page 4 if ET4000 */ ! return svga_open(dev); } } diff -rc2N gs241/gdevsvga.h gs25/gdevsvga.h *** gs241/gdevsvga.h --- gs25/gdevsvga.h Sat Aug 15 09:27:26 1992 *************** *** 0 **** --- 1,85 ---- + /* Copyright (C) 1989, 1992 Aladdin Enterprises. All rights reserved. + Distributed by Free Software Foundation, Inc. + + This file is part of Ghostscript. + + Ghostscript is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY. No author or distributor accepts responsibility + to anyone for the consequences of using it or for whether it serves any + particular purpose or works at all, unless he says so in writing. Refer + to the Ghostscript General Public License for full details. + + Everyone is granted permission to copy, modify and redistribute + Ghostscript, but only under the conditions described in the Ghostscript + General Public License. A copy of this license is supposed to have been + given to you along with Ghostscript so you can know your rights and + responsibilities. It should be in a file named COPYING. Among other + things, the copyright notice and this notice must be preserved on all + copies. */ + + /* gdevsvga.h */ + /* SuperVGA display definitions for Ghostscript */ + /* (requires gdevpcfb.h) */ + + /* Common procedures */ + + /* See gxdevice.h for the definitions of the procedures. */ + + dev_proc_close_device(svga_close); + dev_proc_map_rgb_color(svga_map_rgb_color); + dev_proc_map_color_rgb(svga_map_color_rgb); + dev_proc_fill_rectangle(svga_fill_rectangle); + dev_proc_copy_mono(svga_copy_mono); + dev_proc_copy_color(svga_copy_color); + dev_proc_get_bits(svga_get_bits); + + /* Table structure for looking up graphics modes. */ + typedef struct { + int width, height; /* "key" */ + int mode; /* "value" */ + } mode_info; + + /* The device descriptor structure */ + typedef struct gx_device_svga_s gx_device_svga; + struct gx_device_svga_s { + gx_device_common; + int (*get_mode)(P0()); + void (*set_mode)(P1(int)); + void (*set_page)(P3(gx_device_svga *fbdev, int pnum, int wnum)); + const mode_info _ds *mode; /* BIOS display mode info */ + uint raster; /* frame buffer bytes per line */ + int page; /* current page */ + int wnum_read, wnum_write; /* window #s for read vs. write */ + /* Following are device-specific. */ + union { + struct { + void (*bios_set_page)(P2(int, int)); /* set-page function */ + } vesa; + struct { + int select_reg; /* page-select register */ + } atiw; + struct { + int et_model; /* 4 for ET4000, */ + /* 3 for ET3000 */ + } tseng; + } info; + }; + + /* The initial parameters map an appropriate fraction of */ + /* the screen to an 8.5" x 11" coordinate space. */ + /* This may or may not be what is desired! */ + #define svga_device(procs, name, get_mode, set_mode, set_page) {\ + sizeof(gx_device_svga),\ + &procs,\ + name,\ + 640, 480, /* screen size */\ + 480 / 11.0, 480 / 11.0, /* resolution */\ + no_margins,\ + dci_color(8, 31, 4),\ + 0, /* not opened yet */\ + get_mode, set_mode, set_page\ + } + + /* Utility procedures */ + extern int svga_find_mode(P2(gx_device *, const mode_info _ds *)); + extern int svga_open(P1(gx_device *)); diff -rc2N gs241/gdevtknk.c gs25/gdevtknk.c *** gs241/gdevtknk.c --- gs25/gdevtknk.c Tue Aug 4 01:58:56 1992 *************** *** 0 **** --- 1,254 ---- + /* Copyright (C) 1992 Aladdin Enterprises. All rights reserved. + Distributed by Free Software Foundation, Inc. + + This file is part of Ghostscript. + + Ghostscript is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY. No author or distributor accepts responsibility + to anyone for the consequences of using it or for whether it serves any + particular purpose or works at all, unless he says so in writing. Refer + to the Ghostscript General Public License for full details. + + Everyone is granted permission to copy, modify and redistribute + Ghostscript, but only under the conditions described in the Ghostscript + General Public License. A copy of this license is supposed to have been + given to you along with Ghostscript so you can know your rights and + responsibilities. It should be in a file named COPYING. Among other + things, the copyright notice and this notice must be preserved on all + copies. */ + + /* gdevtknk.c */ + /* + Tektronix Ink-jet plotter driver for Ghostscript. + This code is written for 4696 and 4695 plotters, it may easily be + adopted to the 4393 and 4394 models as well, simply by adding new + device descriptors with other geometrical characteristics. + */ + #include + #include "gdevprn.h" + + /* Thanks to Karsten Spang (spang@nbivax.nbi.dk) for contributing */ + /* this code to Ghostscript. */ + + + /* The device descriptor */ + /* We need our own color mapping procedures. */ + private dev_proc_map_rgb_color(tekink_map_rgb_color); + private dev_proc_map_color_rgb(tekink_map_color_rgb); + private dev_proc_print_page(tekink_print_page); + private gx_device_procs tekink_procs = + prn_color_procs(gdev_prn_open, gdev_prn_output_page, gdev_prn_close, + tekink_map_rgb_color, tekink_map_color_rgb); + + + /* + Device descriptor for the Tek 4696. + The 4696 plotter uses roll media, thus the y size is arbitrary. The + value below is chosen to make the image area A*-format like, i.e. the + aspect ratio is close to sqrt(2). + */ + gx_device_printer gs_tek4696_device = + prn_device(tekink_procs,"tek4696", + 85,120, /* Page size in 10th of inches */ + 120,120, /* Resolution in DPI */ + 0.0,0.0,0.0,0.0, /* Margins */ + 4, /* Bits per pixel */ + tekink_print_page); + + /* Color mapping. + The tek inkjets use subtractive colors B=0 M=1 Y=2 C=3. These are + represented as 4 bits B=1 M=2 Y=4 C=8 in a byte. This gives: + White = 0 + Black = 1 + Magenta = 2 + Yellow = 4 + Red = 6 + Cyan = 8 + Blue = 10 + Green = 12 + The remaining values are unused. (They give ugly results if sent to the + plotter.) Of course this could have been compressed into 3 bits, but + as the palette color memory device uses 8 bits anyway, this is easier, + and perhaps faster. + */ + + static gx_color_index rgb_to_index[8]={1,6,12,4,10,2,8,0}; + static ushort index_to_rgb[16][3]={ + {65535,65535,65535}, /* White */ + {0,0,0}, /* Black */ + {65535,0,65535}, /* Magenta */ + {2,2,2}, /* Unused */ + {65535,65535,0}, /* Yellow */ + {2,2,2}, /* Unused */ + {65535,0,0}, /* Red */ + {2,2,2}, /* Unused */ + {0,65535,65535}, /* Cyan */ + {2,2,2}, /* Unused */ + {0,0,65535}, /* Blue */ + {2,2,2}, /* Unused */ + {0,65535,0}, /* Green */ + {2,2,2}, /* Unused */ + {2,2,2}, /* Unused */ + {2,2,2} /* Unused */ + }; + + /* Map an RGB color to a printer color. */ + private gx_color_index + tekink_map_rgb_color(gx_device *dev, ushort r, ushort g, ushort b) + { + return(rgb_to_index[(((b>32767) << 2) + ((g>32767) << 1) + + (r>32767)) & 7]); + } + + /* Map the printer color back to RGB. */ + private int + tekink_map_color_rgb(gx_device *dev, gx_color_index color, ushort prgb[3]) + { + register ushort c = (ushort)color; + register int i; + if (c>15) return -1; + if (index_to_rgb[c][0]==2) return -1; + for (i=0;i<3;i++){ + prgb[i]=index_to_rgb[c][i]; + } + return 0; + } + + /* Send the page to the printer. */ + private int + tekink_print_page(gx_device_printer *pdev,FILE *prn_stream) + { + int line_size,color_line_size,scan_line,num_bytes,scan_lines,color_plane; + int roll_paper,out_line,micro_line,pending_micro_lines,line_blank, + blank_lines; + byte *outdata,*indata1,*bdata1,*mdata1,*ydata1,*cdata1; + register byte *indata,*bdatap,*mdatap,*ydatap,*cdatap; + register byte bdata,mdata,ydata,cdata; + register byte mask,inbyte; + register byte *indataend,*outdataend; + + /* Allocate a temporary buffer for color separation. + The buffer is partitioned into an input buffer and four + output buffers for the color planes. The output buffers + are allocated with an extra sentinel byte. */ + + line_size = gdev_mem_bytes_per_scan_line((gx_device *)pdev); + color_line_size=(pdev->width+7)/8; + indata1=(byte *)malloc(line_size+4*(color_line_size+1)); + if (indata1==NULL) return -1; + /* pointers to the partions */ + indataend=indata1+line_size; + bdata1=indataend; + mdata1=bdata1+(color_line_size+1); + ydata1=mdata1+(color_line_size+1); + cdata1=ydata1+(color_line_size+1); + + /* Does this device use roll paper? */ + roll_paper=!strcmp(pdev->dname,"tek4696"); + + out_line=0; + blank_lines=0; + scan_lines=pdev->height; + for (scan_line=0;scan_line>=1; + if (!mask){ + *(bdatap++) = bdata; + *(mdatap++) = mdata; + *(cdatap++) = cdata; + *(ydatap++) = ydata; + bdata=0; + mdata=0; + cdata=0; + ydata=0; + mask=0x80; + } + } + if (mask!=0x80){ + *bdatap = bdata; + *mdatap = mdata; + *cdatap = cdata; + *ydatap = ydata; + } + line_blank=1; + /* Output each of the four color planes */ + for (color_plane=0;color_plane<4;color_plane++){ + outdata=indataend+(color_plane*(color_line_size+1)); + outdataend=outdata+color_line_size; + + /* Remove trailing spaces and output the color line if it is + not blank */ + *outdata=0xff; + while (!(*outdataend)) outdataend--; + if (num_bytes=(outdataend-outdata)){ + line_blank=0; + /* On encountering the first non-blank data, output pending + blank lines */ + if (blank_lines){ + pending_micro_lines=((out_line+blank_lines+1)/4)- + (out_line/4); + for (micro_line=0;micro_line> 1, lr2 = lm1 >> 2; *************** *** 28,31 **** --- 32,43 ---- fprintf(f, "/* Parameters derived from machine and compiler architecture */\n\n"); fprintf(f, "#define arch_is_big_endian %d\n", 1 - *(char *)&one); + fprintf(f, "#define arch_align_short_mod %d\n", + (char *)&ss.s - &ss.c); + fprintf(f, "#define arch_align_long_mod %d\n", + (char *)&sl.l - &sl.c); + fprintf(f, "#define arch_align_float_mod %d\n", + (char *)&sf.f - &sf.c); + fprintf(f, "#define arch_align_double_mod %d\n", + (char *)&sd.d - &sd.c); fprintf(f, "#define arch_sizeof_short %d\n", sizeof(short)); fprintf(f, "#define arch_sizeof_int %d\n", sizeof(int)); diff -rc2N gs241/ghost.h gs25/ghost.h *** gs241/ghost.h Mon Apr 20 17:15:12 1992 --- gs25/ghost.h Sat Aug 8 08:23:12 1992 *************** *** 21,202 **** /* Common definitions for Ghostscript */ #include "gx.h" ! ! /* The typedef for object references */ ! typedef struct ref_s ref; ! ! /* ! * Object types. This should be an enum, but there is no way ! * to declare an enum a subrange of byte rather than int.... ! * The types marked with + use the read/write/execute attributes; ! * the rest only use the executable attribute. ! */ ! typedef enum { ! t_array, /* + value.refs, uses size */ ! t_boolean, /* value.index */ ! t_condition, /* value.pcond */ ! t_dictionary, /* + value.pdict */ ! t_file, /* + value.pfile */ ! t_fontID, /* value.pfont */ ! t_gstate, /* value.pgstate */ ! t_integer, /* value.intval */ ! t_lock, /* value.plock */ ! t_mark, /* (no value) */ ! t_name, /* value.pname */ ! t_null, /* (no value) */ ! t_operator, /* value.opproc, uses size */ ! t_real, /* value.realval */ ! t_save, /* value.psave */ ! t_string, /* + value.bytes, uses size */ ! /* The following are the two implementations of packed arrays. */ ! t_mixedarray, /* + value.packed, uses size */ ! t_shortarray, /* + value.packed, uses size */ ! /* ! * The following are extensions to the PostScript type set. ! * When adding new types, be sure to edit the table in gs_init.ps ! * (==only operator), the printing routine in idebug.c, the dispatch ! * in interp.c, obj_eq in iutil.c, restore_check_stack in zvmem.c, ! * and also type_name_strings and type_print_strings below. ! */ ! t_color, /* value.pcolor */ ! t_device, /* value.pdevice */ ! t_oparray, /* (no value), uses size */ ! t_next_index /*** first available index ***/ ! } ref_type; ! /* ! * The interpreter uses types starting at t_next_index for representing ! * a few high-frequency operators. ! * Since there are no operations specifically on operators, ! * there is no need for any operators to check specifically for these ! * types. The r_btype macro takes care of the conversion when required. ! */ ! /* ! * Define the types that use the size field. ! */ ! #define case_types_with_size\ ! case t_array: case t_operator: case t_string:\ ! case t_mixedarray: case t_shortarray: case t_oparray ! /* ! * Define the type names for debugging printout. ! * All names must be the same length, so that columns will line up. ! */ ! #define type_print_strings\ ! "arry","bool","cond","dict","file","font","gstt","int ","lock","mark",\ ! "name","null","oper","real","save","str ","mpry","spry","colr","devc",\ ! "opry" ! /* ! * Define the type names for the type operator. ! */ ! #define type_name_strings\ ! "arraytype","booleantype","conditiontype","dicttype","filetype",\ ! "fonttype","gstatetype","integertype","locktype","marktype",\ ! "nametype","nulltype","operatortype","realtype","savetype",\ ! "stringtype","packedarraytype","packedarraytype","colortype","devicetype",\ ! "operatortype" ! ! /* ! * The encoding of attributes is constrained by two factors: ! * ! * - The packed array format requires the high-order bits of the ! * type/attributes field to be 0. (see packed.h) ! * ! * - The interpreter wants the type, executable bit, and execute ! * permission to be adjacent, and in that order from high to low. ! * ! * The layout given below is the one that leads to the most efficient ! * dispatching in the interpreter. ! */ ! ! /* Location attributes */ ! /* Note that these are associated with the *location*, not with the */ ! /* ref that is *stored* in that location. */ ! #define l_mark 1 /* mark for garbage collector */ ! /* (not used yet) */ ! #define l_new 2 /* stored into since last save */ ! #define l_space 4 /* local vs. global space */ ! /* (not used yet) */ ! #define a_write 8 ! #define a_read 0x10 ! #define a_execute 0x20 ! #define a_executable 0x40 ! #define a_all (a_write+a_read+a_execute) ! #define r_type_shift 7 ! #define r_type_bits 6 ! ! /* Define the attribute names for debugging printout. */ ! #define attr_print_string "mnswrxe......???" ! ! /* Abstract types */ ! typedef struct dict_s dict; ! typedef struct name_s name; ! /* We define a dummy type for op_proc_p so that */ ! /* we don't have to include oper.h. */ ! typedef int (*dummy_op_proc_p)(); ! #define real_opproc(pref) (*(op_proc_p *)&(pref)->value) ! ! /* Object reference */ ! /* ! * Note that because of the way packed arrays are represented, ! * the type_attrs member must be the first one in the ref structure. ! */ ! struct stream_s; ! struct gs_font_s; ! struct gs_color_s; ! struct gs_condition_s; ! struct gs_lock_s; ! struct gx_device_s; ! struct gstate_obj_s; ! struct vm_save_s; ! struct tas_s { ! ushort type_attrs; ! ushort rsize; ! }; ! struct ref_s { ! ! struct tas_s tas; ! ! #define r_size(rp) ((rp)->tas.rsize) ! #define r_inc_size(rp,inc) ((rp)->tas.rsize += (inc)) ! #define r_set_size(rp,siz) ((rp)->tas.rsize = (siz)) ! /* type_attrs is a single element for fast dispatching in the interpreter */ ! #define r_type(rp) ((rp)->tas.type_attrs >> r_type_shift) ! #define r_has_type(rp,typ) r_has_type_attrs(rp,typ,0) /* see below */ ! #define r_set_type(rp,typ) ((rp)->tas.type_attrs = (typ) << r_type_shift) ! #define r_btype(rp)\ ! ((rp)->tas.type_attrs >= (t_next_index << r_type_shift) ?\ ! t_operator : r_type(rp)) ! #define type_xe(tas) ((tas) >> (r_type_shift - 2)) ! #define r_type_xe(rp) type_xe((rp)->tas.type_attrs) ! #define type_xe_value(t,xe) type_xe(((t) << r_type_shift) + (xe)) ! #define r_type_attrs(rp) ((rp)->tas.type_attrs) /* reading only */ ! #define r_has_attrs(rp,mask) !(~r_type_attrs(rp) & (mask)) ! #define r_has_attr(rp,mask1) /* optimize 1-bit case */\ ! (r_type_attrs(rp) & (mask1)) ! #define r_has_type_attrs(rp,typ,mask)\ ! (((rp)->tas.type_attrs & ((((1 << r_type_bits) - 1) << r_type_shift)\ ! + (mask))) ==\ ! (((typ) << r_type_shift) + (mask))) ! #define r_set_attrs(rp,mask) ((rp)->tas.type_attrs |= (mask)) ! #define r_clear_attrs(rp,mask) ((rp)->tas.type_attrs &= ~(mask)) ! #define r_set_type_attrs(rp,typ,mask)\ ! ((rp)->tas.type_attrs = ((typ) << r_type_shift) + (mask)) ! ! union v { /* name the union to keep gdb happy */ ! long intval; ! ushort index; /* for enumerated things */ ! float realval; ! byte *bytes; ! struct ref_s *refs; ! name *pname; ! dict *pdict; ! ushort *packed; ! dummy_op_proc_p opproc; ! struct stream_s *pfile; ! struct gs_font_s *pfont; ! struct gs_color_s *pcolor; ! struct gs_condition_s *pcond; ! struct gs_lock_s *plock; ! struct gx_device_s *pdevice; ! struct gstate_obj_s *pgstate; ! struct vm_save_s *psave; ! } value; ! }; --- 21,23 ---- /* Common definitions for Ghostscript */ #include "gx.h" ! #include "iref.h" diff -rc2N gs241/gp.h gs25/gp.h *** gs241/gp.h Wed Apr 8 00:20:26 1992 --- gs25/gp.h Tue Jul 14 06:26:32 1992 *************** *** 59,63 **** */ ! struct gx_device_s; /* Write a string to the console. */ --- 59,66 ---- */ ! #ifndef gx_device_DEFINED ! # define gx_device_DEFINED ! typedef struct gx_device_s gx_device; ! #endif /* Write a string to the console. */ *************** *** 65,72 **** /* Make the console current on the screen. */ ! extern int gp_make_console_current(P1(struct gx_device_s *)); /* Make the graphics current on the screen. */ ! extern int gp_make_graphics_current(P1(struct gx_device_s *)); /* ------ Printer accessing ------ */ --- 68,75 ---- /* Make the console current on the screen. */ ! extern int gp_make_console_current(P1(gx_device *)); /* Make the graphics current on the screen. */ ! extern int gp_make_graphics_current(P1(gx_device *)); /* ------ Printer accessing ------ */ *************** *** 94,97 **** --- 97,109 ---- extern const int gp_file_names_ignore_case; + /* Define the string to be concatenated with the file mode */ + /* for opening files without end-of-line conversion. */ + /* This is always either "" or "b". */ + extern const char gp_fmode_binary_suffix[]; + /* Define the file modes for binary reading or writing. */ + /* (This is just a convenience: they are "r" or "w" + the suffix.) */ + extern const char gp_fmode_rb[]; + extern const char gp_fmode_wb[]; + /* Create and open a scratch file with a given name prefix. */ /* Write the actual file name at fname. */ *************** *** 105,110 **** /* Answer the string to be used for combining a directory/device prefix */ /* with a base file name. The file name is known to not be absolute. */ ! extern char *gp_file_name_concat_string(P4(const char *prefix, uint plen, ! const char *fname, uint len)); /* ------ File operations ------ */ --- 117,123 ---- /* Answer the string to be used for combining a directory/device prefix */ /* with a base file name. The file name is known to not be absolute. */ ! extern const char * ! gp_file_name_concat_string(P4(const char *prefix, uint plen, ! const char *fname, uint len)); /* ------ File operations ------ */ diff -rc2N gs241/gp_itbc.c gs25/gp_itbc.c *** gs241/gp_itbc.c Mon Apr 13 05:57:00 1992 --- gs25/gp_itbc.c Wed Jun 10 11:29:10 1992 *************** *** 31,34 **** --- 31,37 ---- #endif + /* Library routines not declared in a standard header */ + extern char *getenv(P1(const char *)); + /* Define the size of the C stack. */ unsigned _stklen = 8000; /* default is 4096, we need more */ *************** *** 96,100 **** } #endif - _fmode = O_BINARY; /* Open files in 'binary' mode */ #ifdef __OVERLAY__ --- 99,102 ---- *************** *** 167,171 **** FILE * gp_open_scratch_file(const char *prefix, char *fname, const char *mode) ! { strcpy(fname, prefix); strcat(fname, "XXXXXX"); mktemp(fname); --- 169,183 ---- FILE * gp_open_scratch_file(const char *prefix, char *fname, const char *mode) ! { char *temp; ! if ( (temp = getenv("TEMP")) == NULL ) ! *fname = 0; ! else ! { strcpy(fname, temp); ! /* Prevent X's in path from being converted by mktemp. */ ! for ( temp = fname; *temp; temp++ ) ! *temp = tolower(*temp); ! strcat(fname, "\\"); ! } ! strcat(fname, prefix); strcat(fname, "XXXXXX"); mktemp(fname); diff -rc2N gs241/gp_iwatc.c gs25/gp_iwatc.c *** gs241/gp_iwatc.c Mon Apr 13 05:57:34 1992 --- gs25/gp_iwatc.c Fri Jul 10 17:53:10 1992 *************** *** 29,34 **** #include "gp.h" ! /* Define the size of the C stack. */ ! unsigned _stklen = 8000; /* default is 4096, we need more */ /* Define a substitute for stdprn (see below). */ --- 29,34 ---- #include "gp.h" ! /* Library routines not declared in a standard header */ ! extern char *getenv(P1(const char *)); /* Define a substitute for stdprn (see below). */ *************** *** 42,47 **** void gp_init() ! { _fmode = O_BINARY; /* Open files in 'binary' mode */ ! gs_stdprn = 0; /* Set up the handler for numeric exceptions. */ signal(SIGFPE, handle_FPE); --- 42,46 ---- void gp_init() ! { gs_stdprn = 0; /* Set up the handler for numeric exceptions. */ signal(SIGFPE, handle_FPE); *************** *** 103,109 **** { /* Unfortunately, Watcom C doesn't provide mktemp, */ /* so we have to simulate it ourselves. */ struct stat fst; char *end; ! strcpy(fname, prefix); strcat(fname, "AA.AAA"); end = fname + strlen(fname) - 1; --- 102,118 ---- { /* Unfortunately, Watcom C doesn't provide mktemp, */ /* so we have to simulate it ourselves. */ + char *temp; struct stat fst; char *end; ! if ( (temp = getenv("TEMP")) == NULL ) ! *fname = 0; ! else ! { strcpy(fname, temp); ! /* Prevent X's in path from being converted by mktemp. */ ! for ( temp = fname; *temp; temp++ ) ! *temp = tolower(*temp); ! strcat(fname, "\\"); ! } ! strcat(fname, prefix); strcat(fname, "AA.AAA"); end = fname + strlen(fname) - 1; diff -rc2N gs241/gp_msdos.c gs25/gp_msdos.c *** gs241/gp_msdos.c Mon Apr 13 05:56:24 1992 --- gs25/gp_msdos.c Tue Jul 14 06:27:38 1992 *************** *** 89,92 **** --- 89,99 ---- const int gp_file_names_ignore_case = 1; + /* Define the string to be concatenated with the file mode */ + /* for opening files without end-of-line conversion. */ + const char gp_fmode_binary_suffix[] = "b"; + /* Define the file modes for binary reading or writing. */ + const char gp_fmode_rb[] = "rb"; + const char gp_fmode_wb[] = "wb"; + /* Answer whether a file name contains a directory/device specification, */ /* i.e. is absolute (not directory- or device-relative). */ *************** *** 101,105 **** /* Answer the string to be used for combining a directory/device prefix */ /* with a base file name. The file name is known to not be absolute. */ ! char * gp_file_name_concat_string(const char *prefix, uint plen, const char *fname, uint len) --- 108,112 ---- /* Answer the string to be used for combining a directory/device prefix */ /* with a base file name. The file name is known to not be absolute. */ ! const char * gp_file_name_concat_string(const char *prefix, uint plen, const char *fname, uint len) diff -rc2N gs241/gp_mswin.c gs25/gp_mswin.c *** gs241/gp_mswin.c --- gs25/gp_mswin.c Fri Jul 17 03:41:34 1992 *************** *** 0 **** --- 1,579 ---- + /* Copyright (C) 1992 Aladdin Enterprises. All rights reserved. + Distributed by Free Software Foundation, Inc. + + This file is part of Ghostscript. + + Ghostscript is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY. No author or distributor accepts responsibility + to anyone for the consequences of using it or for whether it serves any + particular purpose or works at all, unless he says so in writing. Refer + to the Ghostscript General Public License for full details. + + Everyone is granted permission to copy, modify and redistribute + Ghostscript, but only under the conditions described in the Ghostscript + General Public License. A copy of this license is supposed to have been + given to you along with Ghostscript so you can know your rights and + responsibilities. It should be in a file named COPYING. Among other + things, the copyright notice and this notice must be preserved on all + copies. */ + + /* gp_mswin.c */ + /* + * Microsoft Windows 3.n platform support for Ghostscript. + * Original version by Russell Lang and Maurice Castro with help from + * Programming Windows, 2nd Ed., Charles Petzold, Microsoft Press; + * initially created from gp_dosfb.c and gp_itbc.c 5th June 1992. + */ + + #include + #include + #include + #include + #include "gp_mswin.h" + + #include "memory_.h" + #include "gx.h" + #include "gp.h" + #include "gpcheck.h" + #include "gserrors.h" + #include "gxdevice.h" + + #include "dos_.h" + #include + #include + #include + #include "string_.h" + + /* Library routines not declared in a standard header */ + extern char *getenv(P1(const char *)); + + /* ------ from gnuplot winmain.c plus new stuff ------ */ + + + /* limits */ + #define MAXSTR 255 + #define BIGBLK 4096 + + /* Linked list of currently open window devices */ + gx_device *gdev_win_open_list; + + /* public handles */ + HWND FAR hwndeasy; + HANDLE FAR phInstance; + + const char FAR szAppName[] = "Ghostscript"; + char win_prntmp[MAXSTR]; /* filename of PRN temporary file */ + + /* printer structure */ + struct PrStr{ + char far *dev; + char far *out; + char far *drv; + struct PrStr * far next; + }; + + struct PrStr * far prlst = NULL; + struct PrStr * far defprlst = NULL; + static HANDLE FAR lib = 0; + + int FAR PASCAL printselproc(); + BOOL FAR PASCAL AbortProc(); + + /* EasyWin */ + extern POINT _ScreenSize; + extern BOOL _KeyPressed(); + + int main(int argc, char *argv[], char *env[]); + + int win_init = 0; /* flag to know if gp_exit has been called */ + + /* our exit handler */ + void win_exit(void) + { + /* if we didn't exit through gs_exit() then do so now */ + if (win_init) + gs_exit(0); + + fcloseall(); + DestroyWindow(hwndeasy); + } + + extern long far PASCAL WndProc(HWND, WORD, WORD, LONG); + + int PASCAL + WinMain(HANDLE hInstance, HANDLE hPrevInstance, LPSTR lpszCmdLine, int cmdShow) + { + WNDCLASS wndclass; + + char modulename[MAXSTR]; + + /* Initialize the list of open Windows devices */ + gdev_win_open_list = 0; + + /* copy the hInstance into a variable so it can be used */ + phInstance = hInstance; + + /* start up the text window */ + _ScreenSize.y = 50; + _InitEasyWin(); + + /* fix up the EasyWindows window provided by Borland */ + GetModuleFileName(hInstance, (LPSTR) modulename, MAXSTR); + hwndeasy = FindWindow("BCEasyWin", modulename); + SetWindowText(hwndeasy, szAppName); /* change title */ + SetClassWord(hwndeasy, GCW_HICON, LoadIcon(hInstance, "texticon")); + + /* if this is the first Ghostscript then register the window class */ + /* for graphics */ + if (!hPrevInstance) { + wndclass.style = CS_HREDRAW | CS_VREDRAW; + wndclass.lpfnWndProc = WndProc; + wndclass.cbClsExtra = 0; + wndclass.cbWndExtra = 0; + wndclass.hInstance = hInstance; + wndclass.hIcon = LoadIcon(hInstance,"grpicon"); + wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); + wndclass.hbrBackground = GetStockObject(WHITE_BRUSH); + wndclass.lpszMenuName = NULL; + wndclass.lpszClassName = szAppName; + RegisterClass(&wndclass); + } + + (void) atexit(win_exit); /* setup exit handler */ + + main(_argc, _argv, environ); + + /* never reached */ + win_exit(); + return 0; + } + + void destroyproflist() + { + struct PrStr far *cur; + struct PrStr far *next; + + cur = prlst; + prlst = NULL; + while (cur != NULL) + { + free(cur->dev); + free(cur->out); + free(cur->drv); + next = cur->next; + free(cur); + cur = next; + } + if (defprlst != NULL) + { + free(defprlst->dev); + free(defprlst->out); + free(defprlst->drv); + free(defprlst); + defprlst = NULL; + } + } + + HDC FAR getprinter() + { + /* See Petzold, "Programming Windows", ed 2, p721 */ + /* Use Default device and allow others */ + char name[MAXSTR]; + LPSTR dev; + LPSTR drv; + LPSTR out; + FARPROC prslinst; + int dlgret; + char alldev[BIGBLK]; + struct PrStr far *cur = NULL; + struct PrStr far *last = NULL; + char *strptr; + HDC retdc; + + /* get the useful info on the default printer */ + GetProfileString("windows", "device", ",,,", name, MAXSTR); + dev = strtok(name, ","); + drv = strtok(NULL, ", "); + out = strtok(NULL, ", "); + /* if OK store it as default */ + if (dev && drv && out) + { + defprlst = (struct PrStr far *) malloc(sizeof(struct PrStr)); + defprlst->next = NULL; + defprlst->dev = (char far *) malloc(strlen(dev)+1); + defprlst->out = (char far *) malloc(strlen(out)+1); + defprlst->drv = (char far *) malloc(strlen(drv)+1); + _fstrcpy(defprlst->dev, (LPSTR) dev); + _fstrcpy(defprlst->out, (LPSTR) out); + _fstrcpy(defprlst->drv, (LPSTR) drv); + } + + /* find out about the names of other devices */ + GetProfileString("devices", NULL, "", alldev, BIGBLK); + strptr = alldev; + while (*strptr) + { + if (cur == NULL) + { + if (prlst == NULL) + cur = last = prlst = (struct PrStr far *) malloc(sizeof(struct PrStr)); + else + cur = last = prlst->next = (struct PrStr far *) malloc(sizeof(struct PrStr)); + } + else + { + last = last->next = (struct PrStr far *) malloc(sizeof(struct PrStr)); + } + last->dev = (char far *) malloc(strlen(strptr)+1); + _fstrcpy(last->dev, (LPSTR) strptr); + last->next = NULL; + last->drv = NULL; + last->out = NULL; + strptr += strlen(strptr) + 1; + } + + /* find out the details */ + while (cur) + { + GetProfileString("devices", cur->dev, "", name, MAXSTR); + drv = strtok(name, ","); + out = strtok(NULL, ", "); + cur->out = (char far *) malloc(strlen(out)+1); + cur->drv = (char far *) malloc(strlen(drv)+1); + _fstrcpy(cur->out, (LPSTR) out); + _fstrcpy(cur->drv, (LPSTR) drv); + cur = cur->next; + } + + /* open dialog box */ + prslinst = MakeProcInstance(printselproc, phInstance); + dlgret = DialogBox(phInstance, "PRSEL", hwndeasy, prslinst); + if (dlgret == IDCANCEL) + { + destroyproflist(); + return NULL; + } + dlgret = dlgret - IDOK - IDCANCEL; + + if (dlgret == 0) + { + dev = defprlst->dev; + drv = defprlst->drv; + out = defprlst->out; + } + else + { + dlgret--; + cur = prlst; + while (dlgret > 0) + { + cur = cur->next; + dlgret--; + } + + dev = cur->dev; + drv = cur->drv; + out = cur->out; + } + + /* create device context */ + retdc = CreateDC(drv, dev, out, (void *) NULL); + destroyproflist(); + + return retdc; + } + + int FAR PASCAL printselproc(hdlg, wmsg, wparam, lparam) + HWND hdlg; + WORD wmsg; + WORD wparam; + DWORD lparam; + { + struct PrStr far *cur; + LPSTR proutstr; + HWND menu; + int val; + LPSTR dev; + LPSTR drv; + LPSTR out; + char *drvnam; + void (FAR PASCAL *dm)(HWND, HANDLE, LPSTR, LPSTR); + + switch (wmsg) + { + case WM_INITDIALOG: + /* default message */ + if (defprlst != NULL) + { + menu = GetDlgItem(hdlg, DEFPRNSTR); + proutstr = (LPSTR) malloc(strlen(defprlst->dev) + strlen(defprlst->out) + 17); + _fstrcpy(proutstr, (LPSTR) "(Currently "); + _fstrcat(proutstr, defprlst->dev); + _fstrcat(proutstr, (LPSTR) " on "); + _fstrcat(proutstr, defprlst->out); + _fstrcat(proutstr, (LPSTR) ")"); + SetWindowText(menu, (LPSTR) proutstr); + EnableWindow(GetDlgItem(hdlg, DEFPRN), TRUE); + SendMessage(GetDlgItem(hdlg, DEFPRN), BM_SETCHECK, 1, 0L); + } + else + EnableWindow(GetDlgItem(hdlg, DEFPRN), FALSE); + + + /* list of all other printers */ + menu = GetDlgItem(hdlg, PRMNU); + if (prlst == NULL) + EnableWindow(GetDlgItem(hdlg, SPECPRN), FALSE); + else + { + EnableWindow(GetDlgItem(hdlg, SPECPRN), TRUE); + if (defprlst == NULL) + SendMessage(GetDlgItem(hdlg, SPECPRN), BM_SETCHECK, 1, 0L); + } + cur = prlst; + while (cur != NULL) + { + proutstr = (LPSTR) malloc(strlen(cur->dev) + strlen(cur->out) + 5); + _fstrcpy(proutstr, cur->dev); + _fstrcat(proutstr, (LPSTR) " on "); + _fstrcat(proutstr, cur->out); + SendMessage(menu,CB_INSERTSTRING, -1, (LONG) (LPSTR) proutstr); + free(proutstr); + cur = cur->next; + } + SendMessage(menu,CB_SETCURSEL, 0, 0); + return TRUE; + case WM_COMMAND: + switch (wparam) + { + case IDOK: + if (SendMessage(GetDlgItem(hdlg, DEFPRN), BM_GETCHECK, 0, 0L)) + val = 0; + else if (SendMessage(GetDlgItem(hdlg, SPECPRN), BM_GETCHECK, 0, 0L)) + { + menu = GetDlgItem(hdlg, PRMNU); + val = SendMessage(menu,CB_GETCURSEL, 0, 0L)+1; + } + else + EndDialog(hdlg, IDCANCEL); + if (val == CB_ERR) + EndDialog(hdlg, IDCANCEL); /* catch all */ + else + EndDialog(hdlg, val + IDOK + IDCANCEL); + return TRUE; + case IDCANCEL: + EndDialog(hdlg, IDCANCEL); + return TRUE; + case PRSET: + dev = NULL; /* clear the options */ + drv = NULL; + out = NULL; + /* if button DEFAULT get options */ + if (SendMessage(GetDlgItem(hdlg, DEFPRN), BM_GETCHECK, 0, 0L)) + { + dev = defprlst->dev; + drv = defprlst->drv; + out = defprlst->out; + } + /* if button SPECIFIC get options */ + if (SendMessage(GetDlgItem(hdlg, SPECPRN), BM_GETCHECK, 0, 0L)) + { + menu = GetDlgItem(hdlg, PRMNU); + val = SendMessage(menu,CB_GETCURSEL, 0, 0); + cur = prlst; + while (val > 0) + { + cur = cur->next; + val--; + } + dev = cur->dev; + drv = cur->drv; + out = cur->out; + } + + if (dev != NULL) + { + /* allow configuration of printer */ + drvnam = (char *) malloc(strlen(drv) + 5); + strcpy(drvnam, drv); + strcat(drvnam, ".DRV"); + lib = LoadLibrary(drvnam); + free(drvnam); + if (lib >= 32) + { + dm = (void (FAR PASCAL *)()) GetProcAddress(lib, (LPSTR) "DEVICEMODE"); + (*dm)((HWND) hdlg, (HANDLE)lib, (LPSTR) dev, (LPSTR) out); + FreeLibrary(lib); + } + } + return TRUE; + } + break; + } + return FALSE; + } + + BOOL FAR PASCAL AbortProc(HDC hdcPrn, int code) + { + MSG msg; + + while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + return(TRUE); + } + + /* ------ Process message loop ------ */ + /* + * Check messages and interrupts; return true if interrupted. + * This is called frequently - it must be quick! + */ + int + gp_check_interrupts() + { + _KeyPressed(); /* Borland EasyWin message loop */ + return 0; + } + + /* ------ from gp_dosfb.c ------ */ + + /* ------ Screen management ------ */ + + /* Write a string to the console. */ + void + gp_console_puts(const char *str, uint size) + { fwrite(str, 1, size, stdout); + } + + /* Make the console current on the screen. */ + int + gp_make_console_current(struct gx_device_s *dev) + { return 0; + } + + /* Make the graphics current on the screen. */ + int + gp_make_graphics_current(struct gx_device_s *dev) + { return 0; + } + + /* ------ from gp_itbc.c ------ */ + + /* Do platform-dependent initialization. */ + void + gp_init() + { + win_init = 1; + } + + /* Do platform-dependent cleanup. */ + void + gp_exit() + { + win_init = 0; + } + + /* ------ Printer accessing ------ */ + + /* Open a connection to a printer. A null file name means use the */ + /* standard printer connected to the machine, if any. */ + /* Return NULL if the connection could not be opened. */ + extern void gp_set_printer_binary(P1(int)); + FILE * + gp_open_printer(char *fname) + { if ( strlen(fname) == 0 || !strcmp(fname, "PRN") ) + { FILE *pfile; + pfile = gp_open_scratch_file(gp_scratch_file_name_prefix, + win_prntmp, "wb"); + return pfile; + } + else + return fopen(fname, "wb"); + } + + /* Close the connection to the printer. */ + void + gp_close_printer(FILE *pfile, const char *fname) + { + HDC printer; + char *buf; + int *bufcount, count; + FARPROC lpfnAbortProc; + fclose(pfile); + if (strlen(fname) && strcmp(fname,"PRN")) + return; /* a file, not a printer */ + printer = getprinter(); + if (printer != (HDC)NULL) { + if ( (pfile = fopen(win_prntmp,"rb")) != (FILE *)NULL) { + if ( (buf = malloc(4096+2)) != (char *)NULL ) { + bufcount = (int *)buf; + EnableWindow(hwndeasy,FALSE); + lpfnAbortProc = MakeProcInstance(AbortProc,phInstance); + if (Escape(printer, STARTDOC, strlen(szAppName),szAppName, NULL) > 0) { + while (!feof(pfile)) { + count = fread(buf+2,1,4096,pfile); + *bufcount = count; + Escape(printer, PASSTHROUGH, count+2, (LPSTR)buf, NULL); + } + Escape(printer,ENDDOC,0,NULL,NULL); + } + FreeProcInstance(lpfnAbortProc); + EnableWindow(hwndeasy,TRUE); + free(buf); + } + fclose(pfile); + } + DeleteDC(printer); + } + unlink(win_prntmp); + } + + /* ------ File names ------ */ + + /* Create and open a scratch file with a given name prefix. */ + /* Write the actual file name at fname. */ + FILE * + gp_open_scratch_file(const char *prefix, char *fname, const char *mode) + { char *temp; + if ( (temp = getenv("TEMP")) == NULL ) + *fname = 0; + else + { strcpy(fname, temp); + /* Prevent X's in path from being converted by mktemp. */ + for ( temp = fname; *temp; temp++ ) + *temp = tolower(*temp); + strcat(fname, "\\"); + } + strcat(fname, prefix); + strcat(fname, "XXXXXX"); + mktemp(fname); + return fopen(fname, mode); + } + + /* ------ File operations ------ */ + + /* If the file given by fname exists, fill in its status and return 1; */ + /* otherwise return 0. */ + int + gp_file_status(const char *fname, file_status *pstatus) + { FILE *f = fopen(fname, "r"); + long flen; + struct ftime ft; + if ( f == NULL ) return 0; + if ( getftime(fileno(f), &ft) < 0 ) + { fclose(f); + return 0; + } + fseek(f, 0, SEEK_END); + flen = ftell(f); + pstatus->size_pages = (flen + 1023) >> 10; + pstatus->size_bytes = flen; + /* Make a single long value from the ftime structure. */ + pstatus->time_referenced = pstatus->time_created = + ((long)((ft.ft_year << 9) + (ft.ft_month << 5) + ft.ft_day) << 16) + + ((ft.ft_hour << 11) + (ft.ft_min << 5) + ft.ft_tsec); + fclose(f); + return 1; + } diff -rc2N gs241/gp_mswin.h gs25/gp_mswin.h *** gs241/gp_mswin.h --- gs25/gp_mswin.h Fri Jul 17 03:41:04 1992 *************** *** 0 **** --- 1,29 ---- + /* Copyright (C) 1992 Aladdin Enterprises. All rights reserved. + Distributed by Free Software Foundation, Inc. + + This file is part of Ghostscript. + + Ghostscript is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY. No author or distributor accepts responsibility + to anyone for the consequences of using it or for whether it serves any + particular purpose or works at all, unless he says so in writing. Refer + to the Ghostscript General Public License for full details. + + Everyone is granted permission to copy, modify and redistribute + Ghostscript, but only under the conditions described in the Ghostscript + General Public License. A copy of this license is supposed to have been + given to you along with Ghostscript so you can know your rights and + responsibilities. It should be in a file named COPYING. Among other + things, the copyright notice and this notice must be preserved on all + copies. */ + + /* gp_mswin.h */ + /* Definitions common to Ghostscript MS Windows implementation */ + /* (used by both C code and Ghostscript 'resource') */ + + /* Dialog box menu constants */ + #define PRMNU 105 + #define PRSET 106 + #define DEFPRN 107 + #define SPECPRN 108 + #define DEFPRNSTR 109 diff -rc2N gs241/gp_sysv.c gs25/gp_sysv.c *** gs241/gp_sysv.c --- gs25/gp_sysv.c Fri May 8 03:00:36 1992 *************** *** 0 **** --- 1,62 ---- + /* Copyright (C) 1992 Aladdin Enterprises. All rights reserved. + Distributed by Free Software Foundation, Inc. + + This file is part of Ghostscript. + + Ghostscript is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY. No author or distributor accepts responsibility + to anyone for the consequences of using it or for whether it serves any + particular purpose or works at all, unless he says so in writing. Refer + to the Ghostscript General Public License for full details. + + Everyone is granted permission to copy, modify and redistribute + Ghostscript, but only under the conditions described in the Ghostscript + General Public License. A copy of this license is supposed to have been + given to you along with Ghostscript so you can know your rights and + responsibilities. It should be in a file named COPYING. Among other + things, the copyright notice and this notice must be preserved on all + copies. */ + + /* gp_sysv.c */ + /* System V Unix-specific routines for Ghostscript */ + + /* This file contains a couple of standard Unix library procedures */ + /* that a few System V platforms don't provide. */ + #include + #Include + #include + #include + #include + #include + + /* rename */ + int + rename(char *a, char *b) + { if (access(a, 0) == -1 ) + return(-1); + unlink(b); + if ( link(a, b) == -1 ) + return(-1); + if ( unlink(a) == -1 ) + { unlink(b); /* ??? */ + return(-1); + } + return(0); + } + + /* gettimeofday */ + #define HZ 100 /* see sys/params.h */ + int + gettimeofday(struct timeval *tvp, struct timezone *tzp) + { struct tms tms; + static long offset = 0; + long ticks; + + if (!offset) + { time(&offset); + offset -= (times(&tms) / HZ); + } + ticks = times(&tms); + tvp->tv_sec = ticks/HZ + offset; + tvp->tv_usec = (ticks % HZ) * (1000*1000/HZ); + } diff -rc2N gs241/gp_unix.c gs25/gp_unix.c *** gs241/gp_unix.c Wed Apr 8 00:21:34 1992 --- gs25/gp_unix.c Tue Jul 14 06:27:44 1992 *************** *** 56,61 **** if ( gettimeofday(&tp, &tzp) == -1 ) ! { perror("Ghostscript: gettimeofday failed:"); ! exit(-1); } --- 56,61 ---- if ( gettimeofday(&tp, &tzp) == -1 ) ! { lprintf("Ghostscript: gettimeofday failed!\n"); ! gs_exit(1); } *************** *** 95,99 **** /* Make the console current on the screen. */ int ! gp_make_console_current(struct gx_device_s *dev) { return 0; } --- 95,99 ---- /* Make the console current on the screen. */ int ! gp_make_console_current(gx_device *dev) { return 0; } *************** *** 101,105 **** /* Make the graphics current on the screen. */ int ! gp_make_graphics_current(struct gx_device_s *dev) { return 0; } --- 101,105 ---- /* Make the graphics current on the screen. */ int ! gp_make_graphics_current(gx_device *dev) { return 0; } *************** *** 115,122 **** { return (strlen(fname) == 0 ? ! gp_open_scratch_file(gp_scratch_file_name_prefix, fname, "wb") : fname[0] == '|' ? ! popen(fname + 1, "wb") : ! fopen(fname, "wb")); } --- 115,122 ---- { return (strlen(fname) == 0 ? ! gp_open_scratch_file(gp_scratch_file_name_prefix, fname, "w") : fname[0] == '|' ? ! popen(fname + 1, "w") : ! fopen(fname, "w")); } *************** *** 141,144 **** --- 141,151 ---- const int gp_file_names_ignore_case = 0; + /* Define the string to be concatenated with the file mode */ + /* for opening files without end-of-line conversion. */ + const char gp_fmode_binary_suffix[] = ""; + /* Define the file modes for binary reading or writing. */ + const char gp_fmode_rb[] = "r"; + const char gp_fmode_wb[] = "w"; + /* Create and open a scratch file with a given name prefix. */ /* Write the actual file name at fname. */ *************** *** 161,165 **** /* Answer the string to be used for combining a directory/device prefix */ /* with a base file name. The file name is known to not be absolute. */ ! char * gp_file_name_concat_string(const char *prefix, uint plen, const char *fname, uint len) --- 168,172 ---- /* Answer the string to be used for combining a directory/device prefix */ /* with a base file name. The file name is known to not be absolute. */ ! const char * gp_file_name_concat_string(const char *prefix, uint plen, const char *fname, uint len) diff -rc2N gs241/gp_vms.c gs25/gp_vms.c *** gs241/gp_vms.c Wed Apr 8 00:21:12 1992 --- gs25/gp_vms.c Sun Aug 2 16:13:38 1992 *************** *** 144,151 **** FILE * gp_open_printer(char *fname) ! { return ! (strlen(fname) == 0 ? ! gp_open_scratch_file(gp_scratch_file_name_prefix, fname, "wb") : ! fopen(fname, "wb")); } --- 144,162 ---- FILE * gp_open_printer(char *fname) ! { ! if (strlen(fname) == 0) ! { strcpy(fname, gp_scratch_file_name_prefix); ! strcat(fname, "XXXXXX"); ! mktemp(fname); ! } ! ! /* ! Printing must be done exactly byte to byte, using "passall". ! However the standard VMS symbiont does not treat stream-LF ! files correctly in this respect, but throws away \n characters. ! Giving the file the record type "undefined", but accessing it ! as a normal stream-LF file does the trick. ! */ ! return(fopen(fname, "w", "rfm = udf", "ctx = stm")); } *************** *** 167,170 **** --- 178,188 ---- const int gp_file_names_ignore_case = 1; + /* Define the string to be concatenated with the file mode */ + /* for opening files without end-of-line conversion. */ + const char gp_fmode_binary_suffix[] = ""; + /* Define the file modes for binary reading or writing. */ + const char gp_fmode_rb[] = "r"; + const char gp_fmode_wb[] = "w"; + /* Create and open a scratch file with a given name prefix. */ /* Write the actual file name at fname. */ *************** *** 199,206 **** unsigned fscn$v_version : 1; unsigned fscn$v_fill_23 : 1;} flags; str_desc.dsc$w_length = len; str_desc.dsc$a_pointer = fname; ! SYS$FILESCAN (&str_desc, &0L, &flags); if ( flags.fscn$v_directory || flags.fscn$v_root || flags.fscn$v_device || flags.fscn$v_node) return 1; --- 217,225 ---- unsigned fscn$v_version : 1; unsigned fscn$v_fill_23 : 1;} flags; + long zero = 0L; str_desc.dsc$w_length = len; str_desc.dsc$a_pointer = fname; ! SYS$FILESCAN (&str_desc, &zero, &flags); if ( flags.fscn$v_directory || flags.fscn$v_root || flags.fscn$v_device || flags.fscn$v_node) return 1; *************** *** 210,214 **** /* Answer the string to be used for combining a directory/device prefix */ /* with a base file name. The file name is known to not be absolute. */ ! char * gp_file_name_concat_string(const char *prefix, uint plen, const char *fname, uint len) --- 229,233 ---- /* Answer the string to be used for combining a directory/device prefix */ /* with a base file name. The file name is known to not be absolute. */ ! const char * gp_file_name_concat_string(const char *prefix, uint plen, const char *fname, uint len) *************** *** 279,283 **** file_enum * ! gp_enumerate_files_init(const char *pat, uint patlen) { file_enum *pfen; --- 298,302 ---- file_enum * ! gp_enumerate_files_init(const char *pat, uint patlen, proc_alloc_t palloc, proc_free_t pfree) { file_enum *pfen; diff -rc2N gs241/gpcheck.h gs25/gpcheck.h *** gs241/gpcheck.h --- gs25/gpcheck.h Thu Jun 11 15:54:40 1992 *************** *** 0 **** --- 1,40 ---- + /* Copyright (C) 1992 Aladdin Enterprises. All rights reserved. + Distributed by Free Software Foundation, Inc. + + This file is part of Ghostscript. + + Ghostscript is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY. No author or distributor accepts responsibility + to anyone for the consequences of using it or for whether it serves any + particular purpose or works at all, unless he says so in writing. Refer + to the Ghostscript General Public License for full details. + + Everyone is granted permission to copy, modify and redistribute + Ghostscript, but only under the conditions described in the Ghostscript + General Public License. A copy of this license is supposed to have been + given to you along with Ghostscript so you can know your rights and + responsibilities. It should be in a file named COPYING. Among other + things, the copyright notice and this notice must be preserved on all + copies. */ + + /* gpcheck.h */ + /* Interrupt check interface for Ghostscript */ + + /* + * On some platforms, Ghostscript must check periodically for user- + * initiated actions. (Eventually, this may be extended to all platforms, + * to handle multi-tasking within Ghostscript.) Routines that run for + * a long time must periodically call gp_check_interrupts(), and if it + * returns true, must clean up whatever they are doing and return an + * e_interrupted (or gs_error_interrupted) exceptional condition. + * + * On platforms that require an interrupt check, the makefile defines + * a symbol CHECK_INTERRUPTS. Currently this is only the Microsoft + * Windows platform. + */ + + #ifdef CHECK_INTERRUPTS + extern int gp_check_interrupts(P0()); + #else + # define gp_check_interrupts() 0 + #endif diff -rc2N gs241/gs.c gs25/gs.c *** gs241/gs.c Tue Apr 21 05:19:18 1992 --- gs25/gs.c Wed Aug 19 00:55:44 1992 *************** *** 20,29 **** /* gs.c */ /* Driver program for Ghostscript */ ! #include #include "memory_.h" #include "string_.h" #include "ghost.h" #include "alloc.h" #include "estack.h" #include "ostack.h" #include "store.h" --- 20,44 ---- /* gs.c */ /* Driver program for Ghostscript */ ! #include #include "memory_.h" #include "string_.h" + /* Capture stdin/out/err before gs.h redefines them. */ + #include + static FILE *real_stdin, *real_stdout, *real_stderr; + static void + get_real() + { real_stdin = stdin, real_stdout = stdout, real_stderr = stderr; + } + /* Define PROGRAM_NAME before we include std.h */ + #ifndef PROGRAM_NAME + # define PROGRAM_NAME "Ghostscript" + #endif #include "ghost.h" + #include "gxdevice.h" + #include "gxdevmem.h" #include "alloc.h" + #include "errors.h" #include "estack.h" + #include "main.h" #include "ostack.h" #include "store.h" *************** *** 34,63 **** #endif - #ifndef PROGRAM_NAME - # define PROGRAM_NAME "Ghostscript" - #endif - /* Library routines not declared in a standard header */ extern char *getenv(P1(const char *)); ! ! /* Exported data */ ! uint memory_chunk_size = 20000; ! /* File name search paths */ ! const char **gs_lib_paths; ! private int gs_lib_count; ! private char *gs_lib_env_path; ! ! /* Configuration information imported from gconfig.c. */ ! extern const char *gs_lib_default_path; ! extern const char *gs_init_file; ! extern ref gs_init_file_array[]; /* Device procedures imported from gsdevice.c. */ - typedef struct gx_device_s gx_device; extern gx_device *gs_getdevice(P1(int)); extern char *gs_devicename(P1(gx_device *)); ! /* Help string */ ! private char *gs_help1 = "\ Usage: gs [switches] [file1.ps file2.ps ...]\n\ or : gs [switches] [file1.ps ...] -- filen.ps arg1 arg2 ...\n\ --- 49,72 ---- #endif /* Library routines not declared in a standard header */ extern char *getenv(P1(const char *)); ! /* Note: sscanf incorrectly defines its first argument as char * */ ! /* rather than const char *. This accounts for the ugly casts below. */ /* Device procedures imported from gsdevice.c. */ extern gx_device *gs_getdevice(P1(int)); extern char *gs_devicename(P1(gx_device *)); ! /* Other imported data */ ! extern int gs_alloc_debug; ! extern int gs_log_errors; ! extern gx_device *gx_device_list[]; ! ! /* ! * Help strings. We have to break them up into parts, because ! * the Watcom compiler has a limit of 510 characters for a single token. ! * For PC displays, we want to limit the strings to 24 lines. ! */ ! private const char *gs_help1 = "\ Usage: gs [switches] [file1.ps file2.ps ...]\n\ or : gs [switches] [file1.ps ...] -- filen.ps arg1 arg2 ...\n\ *************** *** 64,82 **** The latter passes arg1 ... to the program in filen.ps.\n\ Available devices:\n "; ! /* We have to break help2 up into two parts, because the Watcom compiler */ ! /* has a limit of 510 characters for a single token. */ ! private char *gs_help2a = "\n\ Switches: (you can use # in place of =)\n\ -d[=] define name as token, or null if no token given\n\ ! -gx set width and height (`geometry') for device\n\ -I add prefix to search path\n\ -q `quiet' mode, suppress most messages\n\ ! -r set resolution for initial device\n"; ! private char *gs_help2b = "\ ! -rx set device X and Y resolution separately\n\ -s= define name as string\n\ -sDEVICE= select initial device\n\ ! -sOUTPUTFILE= select output file, embed %d for page #,\n\ ! |command to pipe\n\ `-' alone as a file name means read from stdin non-interactively.\n\ For more information, please read the use.doc file.\n"; --- 73,93 ---- The latter passes arg1 ... to the program in filen.ps.\n\ Available devices:\n "; ! /* We have to break help2 up into parts, because */ ! private const char *gs_help2a = "\n\ Switches: (you can use # in place of =)\n\ + @ treat file like part of the command line\n\ + (to get around DOS command line limit)\n\ -d[=] define name as token, or null if no token given\n\ ! -f read this file even if its name begins with - or @\n"; ! private const char *gs_help2b = "\ ! -gx set width and height (`geometry'), in pixels\n\ -I add prefix to search path\n\ -q `quiet' mode, suppress most messages\n\ ! -r set resolution, in pixels per inch\n"; ! private const char *gs_help2c = "\ -s= define name as string\n\ -sDEVICE= select initial device\n\ ! -sOutputFile= select output file: embed %d for page #,\n\ ! - means stdout, use |command to pipe\n\ `-' alone as a file name means read from stdin non-interactively.\n\ For more information, please read the use.doc file.\n"; *************** *** 83,117 **** /* Forward references */ private int esc_strlen(P1(const char *)); private void esc_strcat(P2(char *, const char *)); ! private void runarg(P4(char **, char *, char *, int)); ! private void run_string(P1(char *)); ! private void init1(), init2(); ! private void set_lib_paths(); ! private void run_file(P2(const char *file_name, int user_errors)); ! private void debug_dump_stack(P1(int code)); /* Parameters set by swproc */ - private int user_errors; private int quiet; private int batch; ! /* Static versions of argc and argv (for -- only) */ ! private int static_argc; ! private char **static_argv; ! ! main(int argc, char *argv[]) ! { int num_files; ! int swproc(P2(char **, char *)); ! void argproc(P2(char **, int)); ! static_argc = argc; ! static_argv = argv; ! /* Do platform-dependent initialization. */ ! /* We have to do this as the very first thing, */ ! /* because it detects attempts to run 80N86 executables (N>0) */ ! /* on incompatible processors. */ ! gp_init(); ! /* Initialize the file search paths */ ! gs_lib_env_path = 0; { char *lib = getenv(GS_LIB); if ( lib != 0 ) --- 94,113 ---- /* Forward references */ + private int swproc(P1(const char *)); + private void argproc(P1(const char *)); + private void cmdproc(P1(const char *)); private int esc_strlen(P1(const char *)); private void esc_strcat(P2(char *, const char *)); ! private void runarg(P4(const char **, const char *, const char *, int)); ! private void run_string(P1(const char *)); /* Parameters set by swproc */ private int quiet; private int batch; ! main(int argc, const char *argv[]) ! { int argi; ! get_real(); ! gs_init0(real_stdin, real_stdout, real_stderr, argc); { char *lib = getenv(GS_LIB); if ( lib != 0 ) *************** *** 121,128 **** } } - gs_lib_paths = - (const char **)gs_malloc(argc + 2, sizeof(char *), "-I array"); - gs_lib_count = 0; - set_lib_paths(); /* Execute files named in the command line, */ /* processing options along the way. */ --- 117,120 ---- *************** *** 131,139 **** batch = 0; quiet = 0; ! user_errors = 1; ! num_files = gs_main(argc, argv, swproc, argproc); ! if ( num_files == 0 ) ! { init2(); } if ( !batch ) run_string("start"); gs_exit(0); --- 123,196 ---- batch = 0; quiet = 0; ! /* If debugging is enabled, trace the device calls. */ ! #ifdef DEBUG ! { extern gx_device *gs_trace_device(P1(gx_device *)); ! extern const gx_device_memory ! mem_mono_device, mem_mapped2_color_device, ! mem_mapped4_color_device, mem_mapped8_color_device, ! mem_true16_color_device, ! mem_true24_color_device, mem_true32_color_device; ! static const gx_device_memory *mdevs[8] = ! { &mem_mono_device, &mem_mapped2_color_device, ! &mem_mapped4_color_device, &mem_mapped8_color_device, ! &mem_true16_color_device, ! &mem_true24_color_device, &mem_true32_color_device, ! 0 ! }; ! extern gx_device gs_clist_device; /* gx_clist_device */ ! static gx_device *cldevs[2] = ! { &gs_clist_device, ! 0 ! }; ! gx_device **pdevs[4]; ! gx_device ***ppdev; ! gx_device **pdev; ! pdevs[0] = gx_device_list; ! pdevs[1] = (gx_device **)mdevs; ! pdevs[2] = cldevs; ! pdevs[3] = 0; ! for ( ppdev = pdevs; *ppdev != 0; ppdev++ ) ! for ( pdev = *ppdev; *pdev != 0; pdev++ ) ! { ! /****** ! gx_device *tdev = gs_trace_device(*pdev); ! if ( tdev == 0 ) ! { lprintf("Can't allocate traced device!\n"); ! gs_exit(1); ! } ! *pdev = tdev; ! ******/ ! } } + #endif + for ( argi = 1; argi < argc; argi++ ) + { const char **argp = &argv[argi]; + const char *arg = *argp; + switch ( *arg ) + { + case '@': + cmdproc(arg); + break; + case '-': + if ( !strcmp(arg, "--") || !strcmp(arg, "-+") ) + { /* run with command line args */ + int nstrs = argc - argi - 2; + if ( nstrs < 0 ) /* no file to run! */ + { puts("Usage: gs ... -- file.ps arg1 ... argn"); + gs_exit(1); + } + runarg(argp + 1, "{userdict /ARGUMENTS [", "] put (", nstrs); + gs_exit(0); + } + else + { if ( swproc(arg) < 0 ) + fprintf(stdout, "Unknown switch %s - ignoring\n", arg); + } + break; + default: + argproc(arg); + } + } + gs_init2(); if ( !batch ) run_string("start"); gs_exit(0); *************** *** 141,147 **** /* Process switches */ ! int ! swproc(char **swp, char *arg) ! { char sw = (*swp)[1]; switch ( sw ) { --- 198,205 ---- /* Process switches */ ! private int ! swproc(const char *arg) ! { char sw = arg[1]; ! arg += 2; /* skip - and letter */ switch ( sw ) { *************** *** 151,172 **** batch = 1; /* Set NOPAUSE so showpage won't try to read from stdin. */ ! { char *d = "-dNOPAUSE"; ! swproc(&d, d); ! } ! init2(); /* Finish initialization */ run_string("(%stdin) (r) file cvx execute"); break; ! case '-': /* run with command line args */ ! case '+': /* ditto */ ! { int nstrs = static_argv + static_argc - (swp + 2); ! if ( nstrs < 0 ) /* no file to run! */ ! { printf("Usage: gs ... -- file.ps arg1 ... argn\n"); ! gs_exit(1); ! } ! runarg(swp + 1, "{userdict /ARGUMENTS [", "] put (", nstrs); ! } ! gs_exit(0); case 'h': /* print help */ ! case '?': fputs(gs_help1, stdout); { int i; --- 209,226 ---- batch = 1; /* Set NOPAUSE so showpage won't try to read from stdin. */ ! swproc("-dNOPAUSE"); ! gs_init2(); /* Finish initialization */ run_string("(%stdin) (r) file cvx execute"); break; ! case 'A': /* trace allocator */ ! gs_alloc_debug = 1; break; ! case 'e': /* log errors */ ! gs_log_errors = 1; break; ! case 'E': /* log errors */ ! gs_log_errors = 2; break; ! case 'f': /* run file of arbitrary name */ ! argproc(arg); break; case 'h': /* print help */ ! case '?': /* ditto */ fputs(gs_help1, stdout); { int i; *************** *** 173,192 **** gx_device *pdev; for ( i = 0; (pdev = gs_getdevice(i)) != 0; i++ ) ! printf(" %s", gs_devicename(pdev)); } fputs(gs_help2a, stdout); fputs(gs_help2b, stdout); gs_exit(0); case 'I': /* specify search path */ ! gs_lib_paths[gs_lib_count] = arg; ! gs_lib_count++; ! set_lib_paths(); break; case 'q': /* quiet startup */ ! { ref vnull; quiet = 1; ! init1(); ! make_null(&vnull); ! initial_enter_name("QUIET", &vnull); } break; case 'D': /* define name */ --- 227,245 ---- gx_device *pdev; for ( i = 0; (pdev = gs_getdevice(i)) != 0; i++ ) ! fprintf(stdout, " %s", gs_devicename(pdev)); } fputs(gs_help2a, stdout); fputs(gs_help2b, stdout); + fputs(gs_help2c, stdout); gs_exit(0); case 'I': /* specify search path */ ! gs_add_lib_path(arg); break; case 'q': /* quiet startup */ ! { ref vtrue; quiet = 1; ! gs_init1(); ! make_true(&vtrue); ! initial_enter_name("QUIET", &vtrue); } break; case 'D': /* define name */ *************** *** 200,206 **** /* Initialize the object memory, scanner, and */ /* name table now if needed. */ ! init1(); if ( eqp == arg ) ! { printf("Usage: -dname, -dname=token, -sname=string\n"); gs_exit(1); } --- 253,259 ---- /* Initialize the object memory, scanner, and */ /* name table now if needed. */ ! gs_init1(); if ( eqp == arg ) ! { puts("Usage: -dname, -dname=token, -sname=string"); gs_exit(1); } *************** *** 207,211 **** if ( eqp == NULL ) { if ( isd ) make_null(&value); ! else make_tasv(&value, t_string, a_read+a_execute, 0, bytes, (byte *)""); } --- 260,264 ---- if ( eqp == NULL ) { if ( isd ) make_null(&value); ! else make_tasv(&value, t_string, a_readonly, 0, bytes, (byte *)""); } *************** *** 219,223 **** code = scan_token(&astream, 0, &value); if ( code ) ! { printf("-dname= must be followed by a valid token\n"); gs_exit(1); } --- 272,276 ---- code = scan_token(&astream, 0, &value); if ( code ) ! { puts("-dname= must be followed by a valid token"); gs_exit(1); } *************** *** 231,235 **** } memcpy(str, eqp, len); ! make_tasv(&value, t_string, a_read+a_execute, len, bytes, (byte *)str); } --- 284,288 ---- } memcpy(str, eqp, len); ! make_tasv(&value, t_string, a_readonly, len, bytes, (byte *)str); } *************** *** 242,248 **** { long width, height; ref value; ! init1(); ! if ( sscanf(arg, "%ldx%ld", &width, &height) != 2 ) ! { printf("-g must be followed by x\n"); gs_exit(1); } --- 295,301 ---- { long width, height; ref value; ! gs_init1(); ! if ( sscanf((char *)arg, "%ldx%ld", &width, &height) != 2 ) ! { puts("-g must be followed by x"); gs_exit(1); } *************** *** 255,274 **** case 'M': /* set memory allocation increment */ { unsigned msize = 0; ! sscanf(arg, "%d", &msize); if ( msize <= 0 || msize >= 64 ) ! { printf("-M must be between 1 and 64\n"); gs_exit(1); } ! memory_chunk_size = msize << 10; } break; case 'r': /* define device resolution */ ! { long xres, yres; ref value; ! init1(); ! switch ( sscanf(arg, "%ldx%ld", &xres, &yres) ) { default: ! printf("-r must be followed by or x\n"); gs_exit(1); case 1: /* -r */ --- 308,327 ---- case 'M': /* set memory allocation increment */ { unsigned msize = 0; ! sscanf((char *)arg, "%d", &msize); if ( msize <= 0 || msize >= 64 ) ! { puts("-M must be between 1 and 63"); gs_exit(1); } ! gs_memory_chunk_size = msize << 10; } break; case 'r': /* define device resolution */ ! { float xres, yres; ref value; ! gs_init1(); ! switch ( sscanf((char *)arg, "%fx%f", &xres, &yres) ) { default: ! puts("-r must be followed by or x"); gs_exit(1); case 1: /* -r */ *************** *** 275,281 **** yres = xres; case 2: /* -rx */ ! make_int(&value, xres); initial_enter_name("DEVICEXRESOLUTION", &value); ! make_int(&value, yres); initial_enter_name("DEVICEYRESOLUTION", &value); } --- 328,334 ---- yres = xres; case 2: /* -rx */ ! make_real(&value, xres); initial_enter_name("DEVICEXRESOLUTION", &value); ! make_real(&value, yres); initial_enter_name("DEVICEYRESOLUTION", &value); } *************** *** 282,285 **** --- 335,348 ---- break; } + case 'Z': + if ( !*arg ) + { /* No options, set all flags */ + memset(gs_debug, 0xff, 128); + } + else + { while ( *arg ) + gs_debug[*arg++ & 127] = 0xff; + } + break; } return 0; *************** *** 308,320 **** /* Process file names */ ! void ! argproc(char **argp, int index) ! { runarg(argp, "{", "(", 0); } private void ! runarg(char **argp, char *pre, char *post, int nstrs) ! { char *arg = *argp; ! static char *pex = ")run}execute"; ! int len = strlen(pre) + esc_strlen(arg) + strlen(post) + strlen(pex) + 1; char *line; int i; --- 371,383 ---- /* Process file names */ ! private void ! argproc(const char *arg) ! { runarg(&arg, "{", "(", 0); } private void ! runarg(const char **argp, const char *pre, const char *post, int nstrs) ! { const char *arg = *argp; ! static const char *pex = ")run}execute"; ! int len = strlen(pre) + esc_strlen(arg) + nstrs * 2 + strlen(post) + strlen(pex) + 1; char *line; int i; *************** *** 321,330 **** for ( i = 1; i <= nstrs; i++ ) len += esc_strlen(argp[i]) + 2; ! init2(); /* Finish initialization */ line = gs_malloc(len, 1, "argproc"); if ( line == 0 ) ! { lprintf("Out of memory!\n"); gs_exit(1); ! } strcpy(line, pre); for ( i = 1; i <= nstrs; i++ ) --- 384,393 ---- for ( i = 1; i <= nstrs; i++ ) len += esc_strlen(argp[i]) + 2; ! gs_init2(); /* Finish initialization */ line = gs_malloc(len, 1, "argproc"); if ( line == 0 ) ! { lprintf("Out of memory!\n"); gs_exit(1); ! } strcpy(line, pre); for ( i = 1; i <= nstrs; i++ ) *************** *** 339,434 **** } private void ! run_string(char *str) ! { int code; ! ref stref; ! make_tasv(&stref, t_string, a_executable + a_read + a_execute, ! strlen(str), bytes, (byte *)str); ! code = gs_interpret(&stref, user_errors); zflush((ref *)0); /* flush stdout */ zflushpage((ref *)0); /* force display update */ ! if ( code ) debug_dump_stack(code), gs_exit(2); ! } ! ! private int init1_done = 0, init2_done = 0; ! private void ! init1() ! { if ( !init1_done ) ! { alloc_init(gs_malloc, gs_free, memory_chunk_size); ! name_init(); ! obj_init(); /* requires name_init */ ! scan_init(); /* ditto */ ! init1_done = 1; ! } ! } ! private void ! init2() ! { init1(); ! if ( !init2_done ) ! { gs_init(); ! zop_init(); ! interp_init(1); /* requires obj_init */ ! op_init(); /* requires obj_init, scan_init */ ! /* Set up the array of additional initialization files. */ ! { ref *ifp = gs_init_file_array; ! ref ifa; ! for ( ; ifp->value.bytes != 0; ifp++ ) ! r_set_size(ifp, strlen((const char *)ifp->value.bytes)); ! make_tasv(&ifa, t_array, a_read + a_execute, ! ifp - gs_init_file_array, refs, ! gs_init_file_array); ! initial_enter_name("INITFILES", &ifa); ! } ! /* Execute the standard initialization file. */ ! run_file(gs_init_file, user_errors); ! init2_done = 1; ! } ! } ! ! /* Complete the list of library search paths. */ ! private void ! set_lib_paths() ! { const char **ppath = &gs_lib_paths[gs_lib_count]; ! if ( gs_lib_env_path != 0 ) *ppath++ = gs_lib_env_path; ! if ( gs_lib_default_path != 0 ) *ppath++ = gs_lib_default_path; ! *ppath = 0; } ! /* Open and execute a file */ ! private int ! run_open(const char *file_name, ref *pfile) ! { ! #define maxfn 200 ! byte fn[maxfn]; ! uint len; ! return lib_file_open(file_name, strlen(file_name), fn, maxfn, ! &len, pfile); ! } private void ! run_file(const char *file_name, int user_errors) ! { ref initial_file; ! int code; ! if ( run_open(file_name, &initial_file) < 0 ) ! { eprintf1("Can't find initialization file %s\n", file_name); gs_exit(1); ! } ! r_set_attrs(&initial_file, a_execute + a_executable); ! code = gs_interpret(&initial_file, user_errors); ! if ( code < 0 ) ! debug_dump_stack(code), gs_exit(1); ! } ! ! /* Debugging code */ ! extern void debug_print_ref(P1(ref *)); ! extern void debug_dump_refs(P3(ref *, uint, char *)); ! extern ref error_object; ! ! /* Dump the stacks after interpretation */ ! private void ! debug_dump_stack(int code) ! { zflush(osp); /* force out buffered output */ ! dprintf1("\nUnexpected interpreter error %d!\nError object: ", code); ! debug_print_ref(&error_object); ! dputc('\n'); ! debug_dump_refs(osbot, osp + 1 - osbot, "Operand stack"); ! debug_dump_refs(esbot, esp + 1 - esbot, "Execution stack"); } --- 402,475 ---- } private void ! run_string(const char *str) ! { int exit_code; ! int code = gs_run_string(str, gs_user_errors, &exit_code); zflush((ref *)0); /* flush stdout */ zflushpage((ref *)0); /* force display update */ ! switch ( code ) ! { ! case 0: ! break; ! case e_Quit: ! gs_exit(0); ! case e_Fatal: ! eprintf1("Unrecoverable error, exit code %d\n", exit_code); ! gs_exit(exit_code); ! default: ! gs_debug_dump_stack(code); ! gs_exit(255); ! } } ! /* Process command line indirection. */ private void ! cmdproc(const char *arg) ! { FILE *f; ! #define cstr_max 128 ! char cstr[cstr_max + 1]; ! arg++; /* skip over @ */ ! f = fopen(arg, "r"); ! if ( f == NULL ) ! { fprintf(stdout, "Unable to open command line file %s\n", arg); gs_exit(1); ! } ! while ( 1 ) ! { register int c; ! register int i; ! while ( isspace(c = fgetc(f)) ) ; ! if ( c == EOF ) break; ! for ( i = 0; ; ) ! { if ( i == cstr_max ) ! { cstr[i] = 0; ! fprintf(stdout, "Command too long: %s\n", cstr); ! gs_exit(1); ! } ! cstr[i++] = c; ! c = fgetc(f); ! if ( c == EOF || isspace(c) ) ! break; ! } ! cstr[i] = 0; ! switch ( cstr[0] ) ! { ! case '@': ! cmdproc(cstr); ! break; ! case '-': ! { /* swproc wants strings to be in the heap! */ ! char *sstr = gs_malloc(i + 1, 1, "cmdproc"); ! if ( sstr == 0 ) ! { lprintf("Out of memory!\n"); ! gs_exit(1); ! } ! strcpy(sstr, cstr); ! if ( swproc(sstr) < 0 ) ! fprintf(stdout, "Unknown switch %s - ignoring\n", sstr); ! } ! break; ! default: ! argproc(cstr); ! } ! } ! fclose(f); } diff -rc2N gs241/gs.def gs25/gs.def *** gs241/gs.def --- gs25/gs.def Fri Jul 31 00:38:52 1992 *************** *** 0 **** --- 1,10 ---- + NAME Ghostscript + DESCRIPTION 'Ghostscript Interpreter' + EXETYPE WINDOWS + CODE MOVEABLE NONDISCARDABLE PRELOAD + DATA MULTIPLE MOVEABLE PRELOAD + HEAPSIZE 256 + STACKSIZE 20000 + EXPORTS WndProc + printselproc + AbortProc diff -rc2N gs241/gs.h gs25/gs.h *** gs241/gs.h Wed Mar 4 17:43:06 1992 --- gs25/gs.h Sun Aug 2 17:34:32 1992 *************** *** 23,33 **** #include "std.h" ! /* Ghostscript never writes directly to stdout. */ ! extern FILE *gs_out; ! #ifdef DEBUG ! extern FILE *gs_debug_out; ! #undef dstderr ! #define dstderr gs_debug_out ! #endif /* Representation of a point. */ --- 23,60 ---- #include "std.h" ! /* Ghostscript never uses stdin/out/err directly. */ ! extern FILE *gs_stdin, *gs_stdout, *gs_stderr; ! ! /* Redefine all the relevant stdio functions to use the above. */ ! /* Some functions we make illegal, rather than redefining them. */ ! #undef stdin ! #define stdin gs_stdin ! #undef stdout ! #define stdout gs_stdout ! #undef stderr ! #define stderr gs_stderr ! #undef fgetchar ! #define fgetchar() fgetc(stdin) ! #undef fputchar ! #define fputchar(c) fputc(c, stdout) ! #undef getchar ! #define getchar() getc(stdin) ! #undef gets ! #define gets Function._gets_.unavailable ! /* We should do something about perror, but since many Unix systems */ ! /* don't provide the strerror function, we can't. (Neither the */ ! /* Ghostscript kernel nor any Aladdin-maintained driver uses perror.) */ ! #undef printf ! #define printf Function._printf_.unavailable ! #undef putchar ! #define putchar(c) fputc(c, stdout) ! #undef puts ! #define puts(s) (fputs(s, stdout), putchar('\n')) ! #undef scanf ! #define scanf Function._scanf_.unavailable ! #undef vprintf ! #define vprintf Function._vprintf_.unavailable ! #undef vscanf ! #define vscanf Function._vscanf_.unavailable /* Representation of a point. */ diff -rc2N gs241/gs.mak gs25/gs.mak *** gs241/gs.mak Tue Apr 21 04:15:04 1992 --- gs25/gs.mak Thu Aug 13 18:41:58 1992 *************** *** 39,44 **** # *** NOT IMPLEMENTED YET. *** # filter - support for Level 2 filters (other than eexec, ! # ASCIIHexEncode/Decode, and PFBDecode, which are ! # always included). # ccfonts - precompile fonts into C, and link them # with the executable. In the standard makefiles, --- 39,44 ---- # *** NOT IMPLEMENTED YET. *** # filter - support for Level 2 filters (other than eexec, ! # ASCIIHexEncode/Decode, NullEncode, PFBDecode, ! # and SubFileDecode, which are always included). # ccfonts - precompile fonts into C, and link them # with the executable. In the standard makefiles, *************** *** 55,58 **** --- 55,61 ---- # OBJ - the extension for relocatable object files (e.g., o or obj). # CCC - the C invocation for normal compilation. + # CCD - the C invocation for files that store into frame buffers or + # device registers. Needed because some optimizing compilers + # will eliminate necessary stores. # CC0 - a C invocation with the fewest possible flags. Needed because # MS-DOS limits the length of command lines to 128 characters. *************** *** 84,102 **** all default: gs$(XE) - test: gt$(XE) - mostlyclean realclean distclean clean: rm -f *.$(OBJ) *.a core gmon.out ! rm -f *.dev gconfig.h obj*.tr lib*.tr rm -f t _temp_* _temp_*.* *.map *.sym ! rm -f ansi2knr$(XE) genarch$(XE) uniq$(XE) arch.h gs$(XE) ! # Auxiliary programs ! # genarch may cause a (deliberate) addressing fault, ! # so we invoke it with a preceding -. arch.h: genarch$(XE) ! - $(EXPP) $(EXP)genarch arch.h # -------------------------------- Library -------------------------------- # --- 87,111 ---- all default: gs$(XE) mostlyclean realclean distclean clean: rm -f *.$(OBJ) *.a core gmon.out ! rm -f *.dev *.d_* arch.h gconfig.h obj*.tr lib*.tr rm -f t _temp_* _temp_*.* *.map *.sym ! rm -f ansi2knr$(XE) echogs$(XE) genarch$(XE) uniq$(XE) ! rm -f gs$(XE) $(BEGINFILES) ! # A rule to do a quick and dirty compilation attempt when first installing ! # Ghostscript. Many of the compilations will fail: follow this with 'make'. ! begin: ! rm -f arch.h genarch$(XE) $(BEGINFILES) ! make arch.h ! - $(CCC) *.c ! rm -f gconfig.$(OBJ) gdev*.$(OBJ) gp_*.$(OBJ) gsmisc.$(OBJ) ! rm -f iccfont.$(OBJ) iinit.$(OBJ) interp.$(OBJ) ! ! # Auxiliary programs arch.h: genarch$(XE) ! $(EXPP) $(EXP)genarch arch.h # -------------------------------- Library -------------------------------- # *************** *** 110,115 **** arch_h=arch.h std_h=std.h $(arch_h) gs_h=gs.h $(std_h) ! gx_h=gx.h $(gs_h) # C library interfaces --- 119,130 ---- arch_h=arch.h std_h=std.h $(arch_h) + gdebug_h=gdebug.h gs_h=gs.h $(std_h) ! gx_h=gx.h $(gs_h) $(gdebug_h) ! ! # Platform interfaces ! ! gp_h=gp.h ! gpcheck_h=gpcheck.h # C library interfaces *************** *** 140,145 **** --- 155,164 ---- gschar_h=gschar.h + gscie_h=gscie.h gscolor_h=gscolor.h + gscolor2_h=gscolor2.h gscoord_h=gscoord.h + gscrypt1_h=gscrypt1.h + gscspace_h=gscspace.h gsfont_h=gsfont.h gsmatrix_h=gsmatrix.h *************** *** 167,171 **** gxop1_h=gxop1.h gxpath_h=gxpath.h ! gxtype1_h=gxtype1.h $(gstype1_h) gzcolor_h=gzcolor.h $(gscolor_h) --- 186,190 ---- gxop1_h=gxop1.h gxpath_h=gxpath.h ! gxtype1_h=gxtype1.h $(gscrypt1_h) $(gstype1_h) gzcolor_h=gzcolor.h $(gscolor_h) *************** *** 181,185 **** $(std_h) $(gsprops_h) $(gsutil_h) ! gxcache.$(OBJ): gxcache.c $(GXERR) \ $(gxfixed_h) $(gxmatrix_h) $(gspaint_h) $(gzdevice_h) $(gzcolor_h) \ $(gxcpath_h) $(gxdevmem_h) $(gxfont_h) $(gxfdir_h) $(gxchar_h) \ --- 200,204 ---- $(std_h) $(gsprops_h) $(gsutil_h) ! gxcache.$(OBJ): gxcache.c $(GXERR) $(gpcheck_h) \ $(gxfixed_h) $(gxmatrix_h) $(gspaint_h) $(gzdevice_h) $(gzcolor_h) \ $(gxcpath_h) $(gxdevmem_h) $(gxfont_h) $(gxfdir_h) $(gxchar_h) \ *************** *** 190,194 **** gxcolor.$(OBJ): gxcolor.c $(GXERR) \ ! $(gxfixed_h) $(gxmatrix_h) $(gxdevice_h) $(gxlum_h) $(gzcolor_h) $(gzht_h) $(gzstate_h) gxcpath.$(OBJ): gxcpath.c $(GXERR) \ --- 209,214 ---- gxcolor.$(OBJ): gxcolor.c $(GXERR) \ ! $(gscspace_h) $(gxfixed_h) $(gxmatrix_h) $(gxdevice_h) $(gxlum_h) \ ! $(gzcolor_h) $(gzht_h) $(gzstate_h) gxcpath.$(OBJ): gxcpath.c $(GXERR) \ *************** *** 198,202 **** $(gxfixed_h) $(gxlum_h) $(gxmatrix_h) $(gzstate_h) $(gzdevice_h) $(gzcolor_h) $(gzht_h) ! gxdraw.$(OBJ): gxdraw.c $(GX) \ $(gxfixed_h) $(gxmatrix_h) $(gxbitmap_h) $(gzcolor_h) $(gzdevice_h) $(gzstate_h) --- 218,222 ---- $(gxfixed_h) $(gxlum_h) $(gxmatrix_h) $(gzstate_h) $(gzdevice_h) $(gzcolor_h) $(gzht_h) ! gxdraw.$(OBJ): gxdraw.c $(GX) $(gpcheck_h) \ $(gxfixed_h) $(gxmatrix_h) $(gxbitmap_h) $(gzcolor_h) $(gzdevice_h) $(gzstate_h) *************** *** 204,207 **** --- 224,231 ---- $(gxfixed_h) $(gxmatrix_h) $(gxdevice_h) $(gzcolor_h) $(gzpath_h) $(gzstate_h) $(gxcpath_h) + gxhint1.$(OBJ): gxhint1.c $(GXERR) \ + $(gxarith_h) $(gxfixed_h) $(gxmatrix_h) $(gxdevmem_h) $(gxchar_h) $(gxfont_h) $(gxtype1_h) \ + $(gzdevice_h) $(gzstate_h) + gxht.$(OBJ): gxht.c $(GXERR) \ $(gxfixed_h) $(gxmatrix_h) $(gxbitmap_h) $(gzstate_h) $(gzcolor_h) $(gzdevice_h) $(gzht_h) *************** *** 213,218 **** $(gxfixed_h) $(gxarith_h) $(gzpath_h) ! gxstroke.$(OBJ): gxstroke.c $(GXERR) \ ! $(gxfixed_h) $(gxarith_h) $(gxmatrix_h) $(gzstate_h) $(gzcolor_h) $(gzdevice_h) $(gzline_h) $(gzpath_h) ###### High-level facilities --- 237,246 ---- $(gxfixed_h) $(gxarith_h) $(gzpath_h) ! gxpcopy.$(OBJ): gxpcopy.c $(GXERR) \ ! $(gxfixed_h) $(gxarith_h) $(gzpath_h) ! ! gxstroke.$(OBJ): gxstroke.c $(GXERR) $(gpcheck_h) \ ! $(gscoord_h) $(gxfixed_h) $(gxarith_h) $(gxmatrix_h) \ ! $(gzstate_h) $(gzcolor_h) $(gzdevice_h) $(gzline_h) $(gzpath_h) ###### High-level facilities *************** *** 222,225 **** --- 250,254 ---- gscolor.$(OBJ): gscolor.c $(GXERR) \ + $(gscspace_h) \ $(gxfixed_h) $(gxmatrix_h) $(gxdevice_h) $(gzstate_h) $(gzcolor_h) $(gzht_h) *************** *** 228,232 **** gsdevice.$(OBJ): gsdevice.c $(GXERR) \ ! $(gsarith_h) $(gsprops_h) $(gsutil_h) $(gxfixed_h) $(gxmatrix_h) $(gxbitmap_h) $(gxdevmem_h) $(gzstate_h) $(gzdevice_h) gsfile.$(OBJ): gsfile.c $(GXERR) \ --- 257,261 ---- gsdevice.$(OBJ): gsdevice.c $(GXERR) \ ! $(gxarith_h) $(gsprops_h) $(gsutil_h) $(gxfixed_h) $(gxmatrix_h) $(gxbitmap_h) $(gxdevmem_h) $(gzstate_h) $(gzdevice_h) gsfile.$(OBJ): gsfile.c $(GXERR) \ *************** *** 234,244 **** gsfont.$(OBJ): gsfont.c $(GXERR) \ ! $(gxdevice_h) $(gxfixed_h) $(gxmatrix_h) $(gxfont_h) $(gxfdir_h) $(gzstate_h) ! gsimage.$(OBJ): gsimage.c $(GXERR) \ ! $(gxfixed_h) $(gxarith_h) $(gxmatrix_h) $(gspaint_h) $(gzcolor_h) $(gzdevice_h) $(gzpath_h) $(gzstate_h) $(gxcpath_h) $(gxdevmem_h) $(gximage_h) ! gsim2out.$(OBJ): gsim2out.c $(GXERR) \ ! $(gsstate_h) $(gsmatrix_h) $(gscoord_h) $(gxfixed_h) $(gxtype1_h) gsline.$(OBJ): gsline.c $(GXERR) \ --- 263,281 ---- gsfont.$(OBJ): gsfont.c $(GXERR) \ ! $(gxdevice_h) $(gxfixed_h) $(gxmatrix_h) $(gxfont_h) $(gxfdir_h) \ ! $(gzstate_h) ! gsimage.$(OBJ): gsimage.c $(GXERR) $(gpcheck_h) \ ! $(gxfixed_h) $(gxarith_h) $(gxmatrix_h) $(gspaint_h) \ ! $(gzcolor_h) $(gzdevice_h) $(gzpath_h) $(gzstate_h) \ ! $(gxcpath_h) $(gxdevmem_h) $(gximage_h) ! ! gsimage2.$(OBJ): gsimage2.c $(GXERR) $(gpcheck_h) \ ! $(gxfixed_h) $(gxarith_h) $(gxmatrix_h) $(gspaint_h) \ ! $(gzcolor_h) $(gzdevice_h) $(gzpath_h) $(gzstate_h) \ ! $(gxcpath_h) $(gxdevmem_h) $(gximage_h) ! gsimpath.$(OBJ): gsimpath.c $(GXERR) \ ! $(gsmatrix_h) $(gsstate_h) $(gspath_h) gsline.$(OBJ): gsline.c $(GXERR) \ *************** *** 251,255 **** $(CCC) -DUSE_ASM=0$(USE_ASM) gsmisc.c ! gspaint.$(OBJ): gspaint.c $(GXERR) \ $(gxfixed_h) $(gxmatrix_h) $(gspaint_h) $(gzpath_h) $(gzstate_h) $(gzdevice_h) $(gxcpath_h) $(gxdevmem_h) $(gximage_h) --- 288,292 ---- $(CCC) -DUSE_ASM=0$(USE_ASM) gsmisc.c ! gspaint.$(OBJ): gspaint.c $(GXERR) $(gpcheck_h) \ $(gxfixed_h) $(gxmatrix_h) $(gspaint_h) $(gzpath_h) $(gzstate_h) $(gzdevice_h) $(gxcpath_h) $(gxdevmem_h) $(gximage_h) *************** *** 263,267 **** $(gxfixed_h) $(gxmatrix_h) $(gzstate_h) $(gzcolor_h) $(gzdevice_h) $(gzht_h) $(gzline_h) $(gzpath_h) ! gstdev.$(OBJ): gstdev.c $(GX) \ $(gxbitmap_h) $(gxdevice_h) $(gxfixed_h) $(gxmatrix_h) --- 300,304 ---- $(gxfixed_h) $(gxmatrix_h) $(gzstate_h) $(gzcolor_h) $(gzdevice_h) $(gzht_h) $(gzline_h) $(gzpath_h) ! gstdev.$(OBJ): gstdev.c $(GXERR) \ $(gxbitmap_h) $(gxdevice_h) $(gxfixed_h) $(gxmatrix_h) *************** *** 284,290 **** ###### Files dependent on the installed devices, features, and platform. ! ###### Generating gconfig.h also generates obj*.tr and lib.tr. ! gconfig.h obj.tr objw.tr lib.tr: devs.mak $(MAKEFILE) $(UNIQ) \ $(DEVICE_DEVS) $(DEVICE_DEVS2) $(DEVICE_DEVS3) $(DEVICE_DEVS4) $(DEVICE_DEVS5)\ $(FEATURE_DEVS) $(PLATFORM).dev --- 321,327 ---- ###### Files dependent on the installed devices, features, and platform. ! # Generating gconfig.h also generates obj*.tr and lib.tr. ! gconfig.h obj.tr objw.tr lib.tr: devs.mak $(MAKEFILE) echogs$(XE) $(UNIQ) \ $(DEVICE_DEVS) $(DEVICE_DEVS2) $(DEVICE_DEVS3) $(DEVICE_DEVS4) $(DEVICE_DEVS5)\ $(FEATURE_DEVS) $(PLATFORM).dev *************** *** 303,314 **** LIB=gschar.$(OBJ) gscolor.$(OBJ) gscoord.$(OBJ) \ ! gsdevice.$(OBJ) gsfile.$(OBJ) gsfont.$(OBJ) \ ! gsimage.$(OBJ) gsim2out.$(OBJ) \ ! gsline.$(OBJ) gsmatrix.$(OBJ) gsmisc.$(OBJ) \ gspaint.$(OBJ) gspath.$(OBJ) gspath2.$(OBJ) \ gsstate.$(OBJ) gstdev.$(OBJ) gstype1.$(OBJ) gsutil.$(OBJ) \ gxcache.$(OBJ) gxclist.$(OBJ) gxcolor.$(OBJ) gxcpath.$(OBJ) \ ! gxdither.$(OBJ) gxdraw.$(OBJ) gxfill.$(OBJ) \ ! gxht.$(OBJ) gxpath.$(OBJ) gxpath2.$(OBJ) gxstroke.$(OBJ) \ gdevmem1.$(OBJ) gdevmem2.$(OBJ) gdevmem3.$(OBJ) gconfig.$(OBJ) --- 340,350 ---- LIB=gschar.$(OBJ) gscolor.$(OBJ) gscoord.$(OBJ) \ ! gsdevice.$(OBJ) gsfile.$(OBJ) gsfont.$(OBJ) gsimage.$(OBJ) gsimage2.$(OBJ) \ ! gsimpath.$(OBJ) gsline.$(OBJ) gsmatrix.$(OBJ) gsmisc.$(OBJ) \ gspaint.$(OBJ) gspath.$(OBJ) gspath2.$(OBJ) \ gsstate.$(OBJ) gstdev.$(OBJ) gstype1.$(OBJ) gsutil.$(OBJ) \ gxcache.$(OBJ) gxclist.$(OBJ) gxcolor.$(OBJ) gxcpath.$(OBJ) \ ! gxdither.$(OBJ) gxdraw.$(OBJ) gxfill.$(OBJ) gxhint1.$(OBJ) gxht.$(OBJ) \ ! gxpath.$(OBJ) gxpath2.$(OBJ) gxpcopy.$(OBJ) gxstroke.$(OBJ) \ gdevmem1.$(OBJ) gdevmem2.$(OBJ) gdevmem3.$(OBJ) gconfig.$(OBJ) *************** *** 321,332 **** ccfont_h=ccfont.h dict_h=dict.h dstack_h=dstack.h errors_h=errors.h estack_h=estack.h ! file_h=file.h font_h=font.h ! ghost_h=ghost.h $(gx_h) ! gp_h=gp.h iutil_h=iutil.h name_h=name.h opdef_h=opdef.h --- 357,370 ---- ccfont_h=ccfont.h dict_h=dict.h + dparam_h=dparam.h dstack_h=dstack.h errors_h=errors.h estack_h=estack.h ! files_h=files.h font_h=font.h ! ghost_h=ghost.h $(gx_h) $(iref_h) ! iref_h=iref.h iutil_h=iutil.h + main_h=main.h name_h=name.h opdef_h=opdef.h *************** *** 336,339 **** --- 374,378 ---- save_h=save.h scanchar_h=scanchar.h + scf_h=scf.h state_h=state.h store_h=store.h *************** *** 340,343 **** --- 379,383 ---- stream_h=stream.h # Nested include files + bfont_h=bfont.h $(font_h) oper_h=oper.h $(gsutil_h) $(iutil_h) $(opdef_h) $(ostack_h) # Include files for optional features *************** *** 348,356 **** comp1_h=comp1.h $(ghost_h) $(oper_h) $(gserrors_h) $(gxfixed_h) $(gxop1_h) ! gdevpccm_h=gdevpccm.h ! gdevpcl_h=gdevpcl.h ! gdevprn_h=gdevprn.h $(memory__h) $(string__h) $(gs_h) \ ! $(gsmatrix_h) $(gxdevice_h) $(gxdevmem_h) $(gxclist_h) ! gdevx_h=gdevx.h ###### Utilities --- 388,393 ---- comp1_h=comp1.h $(ghost_h) $(oper_h) $(gserrors_h) $(gxfixed_h) $(gxop1_h) ! gdevprn_h=gdevprn.h $(memory__h) $(string__h) $(gx_h) \ ! $(gserrors_h) $(gsmatrix_h) $(gxdevice_h) $(gxdevmem_h) $(gxclist_h) ###### Utilities *************** *** 358,365 **** GH=$(AK) $(ghost_h) ! ialloc.$(OBJ): ialloc.c $(AK) $(gs_h) $(alloc_h) $(astate_h) ! iccfont.$(OBJ): iccfont.c $(GH) \ ! $(ghost_h) $(alloc_h) $(ccfont_h) $(dict_h) $(dstack_h) $(errors_h) $(name_h) $(save_h) $(store_h) idebug.$(OBJ): idebug.c $(GH) \ --- 395,402 ---- GH=$(AK) $(ghost_h) ! ialloc.$(OBJ): ialloc.c $(AK) $(gs_h) $(gdebug_h) $(alloc_h) $(astate_h) ! iccfont.$(OBJ): iccfont.c $(GH) gconfig.h \ ! $(ghost_h) $(alloc_h) $(ccfont_h) $(dict_h) $(dstack_h) $(errors_h) $(iutil_h) $(name_h) $(oper_h) $(save_h) $(store_h) idebug.$(OBJ): idebug.c $(GH) \ *************** *** 366,372 **** $(iutil_h) $(dict_h) $(name_h) $(ostack_h) $(opdef_h) $(packed_h) $(store_h) ! idict.$(OBJ): idict.c $(GH) $(alloc_h) $(errors_h) $(name_h) $(packed_h) $(save_h) $(store_h) $(iutil_h) $(dict_h) $(dstack_h) ! iinit.$(OBJ): iinit.c $(GH) gconfig.h $(alloc_h) $(dict_h) $(dstack_h) $(errors_h) $(name_h) $(oper_h) $(store_h) iname.$(OBJ): iname.c $(GH) $(alloc_h) $(errors_h) $(name_h) $(store_h) --- 403,414 ---- $(iutil_h) $(dict_h) $(name_h) $(ostack_h) $(opdef_h) $(packed_h) $(store_h) ! idict.$(OBJ): idict.c $(GH) \ ! $(alloc_h) $(errors_h) $(name_h) $(packed_h) $(save_h) $(store_h) $(iutil_h) $(dict_h) $(dstack_h) ! ! idparam.$(OBJ): idparam.c $(GH) \ ! $(gsmatrix_h) $(dict_h) $(dparam_h) $(errors_h) $(iutil_h) ! iinit.$(OBJ): iinit.c $(GH) gconfig.h \ ! $(alloc_h) $(dict_h) $(dstack_h) $(errors_h) $(name_h) $(oper_h) $(store_h) iname.$(OBJ): iname.c $(GH) $(alloc_h) $(errors_h) $(name_h) $(store_h) *************** *** 378,386 **** iutil.$(OBJ): iutil.c $(GH) \ ! $(errors_h) $(alloc_h) $(dict_h) $(iutil_h) $(name_h) $(ostack_h) $(opdef_h) $(store_h) \ $(gsmatrix_h) $(gxdevice_h) $(gzcolor_h) sfilter.$(OBJ): sfilter.c $(AK) $(std_h) $(scanchar_h) $(stream_h) \ ! $(gxfixed_h) $(gstype1_h) stream.$(OBJ): stream.c $(AK) $(std_h) $(stream_h) $(scanchar_h) --- 420,428 ---- iutil.$(OBJ): iutil.c $(GH) \ ! $(errors_h) $(alloc_h) $(dict_h) $(iutil_h) $(name_h) $(ostack_h) $(opdef_h) $(packed_h) $(store_h) \ $(gsmatrix_h) $(gxdevice_h) $(gzcolor_h) sfilter.$(OBJ): sfilter.c $(AK) $(std_h) $(scanchar_h) $(stream_h) \ ! $(gscrypt1_h) stream.$(OBJ): stream.c $(AK) $(std_h) $(stream_h) $(scanchar_h) *************** *** 398,408 **** zcontrol.$(OBJ): zcontrol.c $(OP) $(estack_h) $(iutil_h) $(store_h) ! zdict.$(OBJ): zdict.c $(OP) $(dict_h) $(dstack_h) $(store_h) zfile.$(OBJ): zfile.c $(OP) $(gp_h) \ ! $(alloc_h) $(estack_h) $(file_h) $(iutil_h) $(save_h) $(stream_h) $(store_h) zfileio.$(OBJ): zfileio.c $(OP) $(gp_h) \ ! $(estack_h) $(file_h) $(store_h) $(stream_h) \ $(gsmatrix_h) $(gxdevice_h) $(gxdevmem_h) --- 440,450 ---- zcontrol.$(OBJ): zcontrol.c $(OP) $(estack_h) $(iutil_h) $(store_h) ! zdict.$(OBJ): zdict.c $(OP) $(dict_h) $(dstack_h) $(name_h) $(store_h) zfile.$(OBJ): zfile.c $(OP) $(gp_h) \ ! $(alloc_h) $(estack_h) $(files_h) $(iutil_h) $(save_h) $(stream_h) $(store_h) zfileio.$(OBJ): zfileio.c $(OP) $(gp_h) \ ! $(estack_h) $(files_h) $(store_h) $(stream_h) \ $(gsmatrix_h) $(gxdevice_h) $(gxdevmem_h) *************** *** 415,419 **** zmisc.$(OBJ): zmisc.c $(OP) $(gp_h) \ $(alloc_h) $(dict_h) $(dstack_h) $(name_h) $(packed_h) $(store_h) \ ! $(gstype1_h) $(gxfixed_h) zpacked.$(OBJ): zpacked.c $(OP) \ --- 457,461 ---- zmisc.$(OBJ): zmisc.c $(OP) $(gp_h) \ $(alloc_h) $(dict_h) $(dstack_h) $(name_h) $(packed_h) $(store_h) \ ! $(gscrypt1_h) zpacked.$(OBJ): zpacked.c $(OP) \ *************** *** 437,441 **** ###### Graphics operators ! zchar.$(OBJ): zchar.c $(OP) $(gxmatrix_h) $(gschar_h) $(gstype1_h) $(gxdevice_h) $(gxfixed_h) $(gxfont_h) $(gzpath_h) $(gzstate_h) $(alloc_h) $(dict_h) $(dstack_h) $(font_h) $(estack_h) $(state_h) $(store_h) zcolor.$(OBJ): zcolor.c $(OP) $(alloc_h) $(estack_h) $(gxfixed_h) $(gxmatrix_h) $(gzstate_h) $(gxdevice_h) $(gzcolor_h) $(iutil_h) $(state_h) $(store_h) --- 479,485 ---- ###### Graphics operators ! zchar.$(OBJ): zchar.c $(OP) $(gxfixed_h) $(gxmatrix_h) \ ! $(gschar_h) $(gxtype1_h) $(gxdevice_h) $(gxfont_h) $(gzpath_h) $(gzstate_h) \ ! $(alloc_h) $(dict_h) $(dstack_h) $(font_h) $(estack_h) $(state_h) $(store_h) zcolor.$(OBJ): zcolor.c $(OP) $(alloc_h) $(estack_h) $(gxfixed_h) $(gxmatrix_h) $(gzstate_h) $(gxdevice_h) $(gzcolor_h) $(iutil_h) $(state_h) $(store_h) *************** *** 444,454 **** zfont.$(OBJ): zfont.c $(OP) $(gsmatrix_h) $(gxdevice_h) $(gxfont_h) $(gxfdir_h) \ ! $(alloc_h) $(font_h) $(dict_h) $(name_h) $(packed_h) $(save_h) $(state_h) $(store_h) zfont1.$(OBJ): zfont1.c $(OP) $(gsmatrix_h) $(gxdevice_h) $(gschar_h) $(gxfixed_h) $(gxfont_h) \ ! $(dict_h) $(font_h) $(name_h) $(store_h) zfont2.$(OBJ): zfont2.c $(OP) $(gsmatrix_h) $(gxdevice_h) $(gschar_h) $(gxfixed_h) $(gxfont_h) \ ! $(alloc_h) $(dict_h) $(font_h) $(name_h) $(packed_h) $(store_h) zgstate.$(OBJ): zgstate.c $(OP) $(alloc_h) $(gsmatrix_h) $(gsstate_h) $(state_h) $(store_h) --- 488,498 ---- zfont.$(OBJ): zfont.c $(OP) $(gsmatrix_h) $(gxdevice_h) $(gxfont_h) $(gxfdir_h) \ ! $(alloc_h) $(bfont_h) $(dict_h) $(name_h) $(packed_h) $(save_h) $(state_h) $(store_h) zfont1.$(OBJ): zfont1.c $(OP) $(gsmatrix_h) $(gxdevice_h) $(gschar_h) $(gxfixed_h) $(gxfont_h) \ ! $(bfont_h) $(dict_h) $(dparam_h) $(name_h) $(store_h) zfont2.$(OBJ): zfont2.c $(OP) $(gsmatrix_h) $(gxdevice_h) $(gschar_h) $(gxfixed_h) $(gxfont_h) \ ! $(alloc_h) $(bfont_h) $(dict_h) $(dparam_h) $(name_h) $(packed_h) $(store_h) zgstate.$(OBJ): zgstate.c $(OP) $(alloc_h) $(gsmatrix_h) $(gsstate_h) $(state_h) $(store_h) *************** *** 458,462 **** zmatrix.$(OBJ): zmatrix.c $(OP) $(gsmatrix_h) $(state_h) $(gscoord_h) $(store_h) ! zpaint.$(OBJ): zpaint.c $(OP) $(alloc_h) $(estack_h) $(gsmatrix_h) $(gspaint_h) $(state_h) $(store_h) zpath.$(OBJ): zpath.c $(OP) $(gsmatrix_h) $(gspath_h) $(state_h) $(store_h) --- 502,506 ---- zmatrix.$(OBJ): zmatrix.c $(OP) $(gsmatrix_h) $(state_h) $(gscoord_h) $(store_h) ! zpaint.$(OBJ): zpaint.c $(OP) $(alloc_h) $(estack_h) $(gsmatrix_h) $(gspaint_h) $(state_h) $(store_h) $(stream_h) zpath.$(OBJ): zpath.c $(OP) $(gsmatrix_h) $(gspath_h) $(state_h) $(store_h) *************** *** 466,470 **** ###### Linking ! INT=ialloc.$(OBJ) idebug.$(OBJ) idict.$(OBJ) iinit.$(OBJ) iname.$(OBJ) \ interp.$(OBJ) isave.$(OBJ) iscan.$(OBJ) iutil.$(OBJ) \ sfilter.$(OBJ) stream.$(OBJ) \ --- 510,515 ---- ###### Linking ! INT=ialloc.$(OBJ) idebug.$(OBJ) idict.$(OBJ) idparam.$(OBJ) \ ! iinit.$(OBJ) iname.$(OBJ) \ interp.$(OBJ) isave.$(OBJ) iscan.$(OBJ) iutil.$(OBJ) \ sfilter.$(OBJ) stream.$(OBJ) \ *************** *** 495,502 **** $(alloc_h) $(dict_h) $(dstack_h) $(iutil_h) $(name_h) $(ostack_h) $(save_h) $(store_h) $(stream_h) $(bseq_h) $(btoken_h) $(bnum_h) ! zbseq.$(OBJ): zbseq.c $(OP) $(save_h) $(store_h) $(stream_h) $(file_h) $(name_h) $(bnum_h) $(btoken_h) $(bseq_h) zdps1.$(OBJ): zdps1.c $(OP) $(gsmatrix_h) $(gspath_h) $(gsstate_h) \ ! $(state_h) $(store_h) $(stream_h) $(bnum_h) zupath.$(OBJ): zupath.c $(OP) \ --- 540,547 ---- $(alloc_h) $(dict_h) $(dstack_h) $(iutil_h) $(name_h) $(ostack_h) $(save_h) $(store_h) $(stream_h) $(bseq_h) $(btoken_h) $(bnum_h) ! zbseq.$(OBJ): zbseq.c $(OP) $(save_h) $(store_h) $(stream_h) $(files_h) $(name_h) $(bnum_h) $(btoken_h) $(bseq_h) zdps1.$(OBJ): zdps1.c $(OP) $(gsmatrix_h) $(gspath_h) $(gsstate_h) \ ! $(alloc_h) $(state_h) $(store_h) $(stream_h) $(bnum_h) zupath.$(OBJ): zupath.c $(OP) \ *************** *** 506,511 **** ### Display PostScript - # We should include zcontext, but it isn't in good enough shape yet. dps_= dps.dev: dpsand2.dev $(dps_) --- 551,557 ---- ### Display PostScript + # We should include zcontext, but it isn't in good enough shape yet: + # $(SHP)gsaddmod dps -oper zcontext dps_= dps.dev: dpsand2.dev $(dps_) *************** *** 514,528 **** zcontext.$(OBJ): zcontext.c $(OP) \ ! $(alloc_h) $(dict_h) $(estack_h) $(state_h) $(store_h) ! ### Level 2 additions -- currently just things common to DPS and Level 2. ! # Should also include ! # $(SHP)gsaddmod level2 -ps gs_lev2 ! level2_= level2.dev: dpsand2.dev $(level2_) $(SHP)gssetmod level2 $(level2_) $(SHP)gsaddmod level2 -include dpsand2 ### Composite font support --- 560,596 ---- zcontext.$(OBJ): zcontext.c $(OP) \ ! $(alloc_h) $(dict_h) $(dstack_h) $(estack_h) $(state_h) $(store_h) ! ### Level 2 additions ! # We should include gscie and zcie, but they aren't anywhere near ready. ! level2_=gscolor2.$(OBJ) zcolor2.$(OBJ) zht2.$(OBJ) zimage2.$(OBJ) level2.dev: dpsand2.dev $(level2_) $(SHP)gssetmod level2 $(level2_) $(SHP)gsaddmod level2 -include dpsand2 + $(SHP)gsaddmod level2 -oper zcolor2 zimage2 + $(SHP)gsaddmod level2 -ps gs_lev2 + + gscie.$(OBJ): gscie.c $(std_h) \ + $(gscspace_h) $(gscie_h) + gscolor2.$(OBJ): gscolor2.c $(GXERR) \ + $(gscolor2_h) $(gscspace_h) $(gxdevice_h) $(gxfixed_h) $(gxmatrix_h) \ + $(gzcolor_h) $(gzstate_h) + + zcie.$(OBJ): zcie.c $(OP) $(gscspace_h) $(gscie_h) \ + $(dict_h) $(dparam_h) $(state_h) + + zcolor2.$(OBJ): zcolor2.c $(OP) \ + $(gscolor_h) $(gscolor2_h) $(gscspace_h) $(gsmatrix_h) \ + $(dict_h) $(dparam_h) $(name_h) $(state_h) $(store_h) + + zht2.$(OBJ): zht2.c $(OP) \ + $(dict_h) $(dparam_h) $(name_h) $(state_h) $(store_h) + + zimage2.$(OBJ): zimage2.c $(OP) \ + $(gscolor_h) $(gscolor2_h) $(gscspace_h) $(gsmatrix_h) \ + $(dict_h) $(dparam_h) $(state_h) + ### Composite font support *************** *** 531,535 **** zfont0.$(OBJ): zfont0.c $(OP) $(gsmatrix_h) $(gxdevice_h) $(gxfont_h) \ ! $(alloc_h) $(font_h) $(dict_h) $(name_h) $(state_h) $(store_h) compfont_=zfont0.$(OBJ) gschar0.$(OBJ) --- 599,603 ---- zfont0.$(OBJ): zfont0.c $(OP) $(gsmatrix_h) $(gxdevice_h) $(gxfont_h) \ ! $(alloc_h) $(bfont_h) $(dict_h) $(name_h) $(state_h) $(store_h) compfont_=zfont0.$(OBJ) gschar0.$(OBJ) *************** *** 538,568 **** $(SHP)gsaddmod compfont -oper zfont0 ! ### Filters other than eexec and ASCIIHex ! sfilter2.$(OBJ): sfilter2.c $(AK) $(std_h) $(scanchar_h) $(stream_h) ! zfilter2.$(OBJ): zfilter2.c $(OP) $(alloc_h) $(stream_h) ! filter_=zfilter2.$(OBJ) sfilter2.$(OBJ) ! filter.dev: $(filter_) ! $(SHP)gssetmod filter $(filter_) ! $(SHP)gsaddmod filter -oper zfilter2 ! ### LZW encoding/decoding ! ### Not included, because Unisys has been awarded a legal monopoly ! ### (patent) on the right to implement the freely published algorithms. ! lzw_=zlzwd.$(OBJ) zlzwe.$(OBJ) slzwd.$(OBJ) slzwe.$(OBJ) ! lzw.dev: $(lzw_) ! $(SHP)gssetmod lzw $(lzw_) ! $(SHP)gsaddmod lzw -oper zlzwd zlzwe ! slzwd.$(OBJ): slzwd.c $(AK) std.h stream.h ! slzwe.$(OBJ): slzwe.c $(AK) std.h stream.h ! zlzwd.$(OBJ): zlzwd.c $(OP) $(alloc_h) $(stream_h) ! zlzwe.$(OBJ): zlzwe.c $(OP) $(alloc_h) $(stream_h) ### Precompiled fonts. See fonts.doc for more information. --- 606,635 ---- $(SHP)gsaddmod compfont -oper zfont0 ! ### Filters other than the ones in sfilter.c ! scftab.$(OBJ): scftab.c $(AK) $(std_h) $(scf_h) ! scfdtab.$(OBJ): scfdtab.c $(AK) $(std_h) $(scf_h) ! scfd.$(OBJ): scfd.c $(AK) $(std_h) $(gdebug_h) $(scf_h) $(stream_h) ! scfe.$(OBJ): scfe.c $(AK) $(std_h) $(gdebug_h) $(scf_h) $(stream_h) ! sfilter2.$(OBJ): sfilter2.c $(AK) $(std_h) $(scanchar_h) $(stream_h) ! slzwd.$(OBJ): slzwd.c $(AK) $(std_h) $(gdebug_h) $(stream_h) ! slzwe.$(OBJ): slzwe.c $(AK) $(std_h) $(gdebug_h) $(stream_h) ! zfilter2.$(OBJ): zfilter2.c $(OP) $(alloc_h) $(dict_h) $(dparam_h) $(stream_h) ! # Because of size limits on the DOS command line, ! # we have to break this up into two parts. ! filter_1=zfilter2.$(OBJ) sfilter2.$(OBJ) ! filter_2=scfd.$(OBJ) scfe.$(OBJ) scfdtab.$(OBJ) scftab.$(OBJ) slzwd.$(OBJ) slzwe.$(OBJ) ! filter.dev: $(filter_1) $(filter_2) ! $(SHP)gssetmod filter $(filter_1) ! $(SHP)gsaddmod filter -obj $(filter_2) ! $(SHP)gsaddmod filter -oper zfilter2 ### Precompiled fonts. See fonts.doc for more information. *************** *** 570,584 **** CCFONT=$(OP) $(ccfont_h) ! ccfonts_=ugly.$(OBJ) cour.$(OBJ) ccfonts.dev: $(ccfonts_) iccfont.$(OBJ) $(SHP)gssetmod ccfonts $(ccfonts_) iccfont.$(OBJ) ! $(SHP)gsaddmod ccfonts -oper font_Ugly font_Courier ugly.$(OBJ): ugly.c $(CCFONT) ! cour.$(OBJ): cour.c $(CCFONT) psyr.$(OBJ): psyr.c $(CCFONT) pzdr.$(OBJ): pzdr.c $(CCFONT) --- 637,654 ---- CCFONT=$(OP) $(ccfont_h) ! ccfonts_=ugly.$(OBJ) ccfonts.dev: $(ccfonts_) iccfont.$(OBJ) $(SHP)gssetmod ccfonts $(ccfonts_) iccfont.$(OBJ) ! $(SHP)gsaddmod ccfonts -oper ccfonts ! $(SHP)gsaddmod ccfonts -font Ugly ugly.$(OBJ): ugly.c $(CCFONT) ! ncrr.$(OBJ): ncrr.c $(CCFONT) psyr.$(OBJ): psyr.c $(CCFONT) + ptmr.$(OBJ): ptmr.c $(CCFONT) + pzdr.$(OBJ): pzdr.c $(CCFONT) *************** *** 585,594 **** # ----------------------------- Main program ------------------------------ # ! # Utilities shared between platforms ! gsmain.$(OBJ): gsmain.c $(GX) \ ! $(gp_h) $(gsmatrix_h) $(gxdevice_h) ! # Interpreter main program interp.$(OBJ): interp.c $(GH) \ --- 655,666 ---- # ----------------------------- Main program ------------------------------ # ! # Interpreter main program ! gs.$(OBJ): gs.c $(GH) $(gxdevice_h) $(gxdevmem_h) \ ! $(alloc_h) $(errors_h) $(estack_h) $(main_h) $(ostack_h) $(store_h) $(stream_h) ! gsmain.$(OBJ): gsmain.c $(GH) \ ! $(gp_h) $(gsmatrix_h) $(gxdevice_h) $(gserrors_h) \ ! $(estack_h) $(main_h) $(ostack_h) $(store_h) interp.$(OBJ): interp.c $(GH) \ *************** *** 595,598 **** $(errors_h) $(estack_h) $(name_h) $(dict_h) $(dstack_h) $(oper_h) $(ostack_h) $(packed_h) $(save_h) $(store_h) $(stream_h) $(CCINT) interp.c - - gs.$(OBJ): gs.c $(GH) $(alloc_h) $(estack_h) $(ostack_h) $(store_h) $(stream_h) --- 667,668 ---- diff -rc2N gs241/gs.rc gs25/gs.rc *** gs241/gs.rc --- gs25/gs.rc Fri Jul 17 03:41:14 1992 *************** *** 0 **** --- 1,21 ---- + #include + #include "gp_mswin.h" + + texticon ICON gstext.ico + + grpicon ICON gsgraph.ico + + + PRSEL DIALOG 8, 31, 251, 79 + CAPTION "Ghostscript" + STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE + BEGIN + CONTROL "", PRMNU, "COMBOBOX", CBS_DROPDOWNLIST | WS_CHILD | WS_VISIBLE | WS_VSCROLL, 21, 49, 179, 60 + PUSHBUTTON "OK", IDOK, 210, 8, 40, 13 + PUSHBUTTON "Cancel", IDCANCEL, 210, 28, 40, 12 + PUSHBUTTON "&Options...", PRSET, 210, 48, 40, 12, WS_CHILD | WS_VISIBLE | WS_TABSTOP + CONTROL "&Default Printer", DEFPRN, "BUTTON", BS_AUTORADIOBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 12, 11, 67, 12 + CONTROL "Specific &Printer", SPECPRN, "BUTTON", BS_AUTORADIOBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 12, 36, 65, 12 + CONTROL "", DEFPRNSTR, "STATIC", SS_LEFT | WS_CHILD | WS_VISIBLE, 21, 24, 180, 12 + CONTROL "Printer", 112, "button", BS_GROUPBOX | WS_CHILD | WS_VISIBLE | WS_GROUP, 7, 2, 199, 61 + END diff -rc2N gs241/gs.tr gs25/gs.tr *** gs241/gs.tr Sun Apr 12 15:05:16 1992 --- gs25/gs.tr Thu Aug 13 18:42:06 1992 *************** *** 1,4 **** gs gsmain+ ! ialloc idebug idict iinit iname+ interp isave iscan iutil sfilter stream+ zarith zarray zcontrol zdict+ --- 1,4 ---- gs gsmain+ ! ialloc idebug idict idparam iinit iname+ interp isave iscan iutil sfilter stream+ zarith zarray zcontrol zdict+ *************** *** 8,14 **** zht zmatrix zpaint zpath zpath2+ gschar gscolor gscoord gsdevice gsfile+ ! gsfont gsimage gsim2out gsline gsmatrix gsmisc+ gspaint gspath gspath2 gsstate gstdev gstype1 gsutil+ gxcache gxclist gxcolor gxcpath gxdither gxdraw gxfill+ ! gxht gxpath gxpath2 gxstroke+ gdevmem1 gdevmem2 gdevmem3 gconfig+ --- 8,14 ---- zht zmatrix zpaint zpath zpath2+ gschar gscolor gscoord gsdevice gsfile+ ! gsfont gsimage gsimage2 gsimpath gsline gsmatrix gsmisc+ gspaint gspath gspath2 gsstate gstdev gstype1 gsutil+ gxcache gxclist gxcolor gxcpath gxdither gxdraw gxfill+ ! gxhint1 gxht gxpath gxpath2 gxpcopy gxstroke+ gdevmem1 gdevmem2 gdevmem3 gconfig+ diff -rc2N gs241/gs_2asc.ps gs25/gs_2asc.ps *** gs241/gs_2asc.ps Sun Dec 8 04:12:28 1991 --- gs25/gs_2asc.ps Sun Jul 26 02:30:38 1992 *************** *** 1,3 **** ! % Copyright (C) 1991 Aladdin Enterprises. All rights reserved. % Distributed by Free Software Foundation, Inc. % --- 1,3 ---- ! % Copyright (C) 1991, 1992 Aladdin Enterprises. All rights reserved. % Distributed by Free Software Foundation, Inc. % *************** *** 20,36 **** % Extract the ASCII text from a PostScript file. Nothing is displayed. % Instead, lines are written to stdout as follows: ! % F - indicate font height ! % S () - display a string ! % P - end of page ! % is an integer expressed in device pixels. ! % and are integer device coordinates. is a string ! % represented with the standard PostScript escape conventions. % The idea is similar to Glenn Reid's `distillery', only a lot more % simple-minded, and less robust. ! % Note that this code will only work properly if systemdict is writable. ! % For this reason, it is normally read in by gs_init.ps before ! % systemdict is made read-only. /QUIET true def systemdict wcheck { systemdict } { userdict } ifelse begin --- 20,47 ---- % Extract the ASCII text from a PostScript file. Nothing is displayed. % Instead, lines are written to stdout as follows: ! % F () ! % indicate font height and width of a space ! % S () ! % display a string ! % P ! % end of page ! % ! % is an integer expressed in tenths of a point ! % is an integer in tenths of a point. ! % and are integer coordinates, in tenths of a point, with origin ! % at lower left. ! % and are string represented with the standard ! % PostScript escape conventions. % The idea is similar to Glenn Reid's `distillery', only a lot more % simple-minded, and less robust. ! % Note that this code will only work properly if systemdict is writable ! % and if `binding' the definitions of operators defined as procedures ! % is deferred. For this reason, it is normally invoked with ! % gs -q -dNOBIND -dWRITESYSTEMDICT gs_2asc.ps + % Thanks to J Greely for improvements + % to this code. + /QUIET true def systemdict wcheck { systemdict } { userdict } ifelse begin *************** *** 43,48 **** /stroke { newpath } odef ! % Image and imagemask must read the input, but do nothing. /image { gsave nulldevice //image grestore } odef /imagemask { gsave nulldevice //imagemask grestore } odef --- 54,60 ---- /stroke { newpath } odef ! % The image operators must read the input, but do nothing. + /colorimage { gsave nulldevice //colorimage grestore } odef /image { gsave nulldevice //image grestore } odef /imagemask { gsave nulldevice //imagemask grestore } odef *************** *** 51,73 **** /copypage { (P\n) //print } odef ! /showpage { copypage erasepage } odef % Redefine `show'. ! /.show.ident matrix def /.showfont ! { 0 currentfont /FontBBox get dup 3 get exch 1 get sub ! currentfont /FontMatrix get dtransform dtransform ! exch abs exch abs max round ! (F ) //print //.stdout exch write==only (\n) //print } odef /.showstring ! { gsave //.show.ident setmatrix ! (S ) //print currentpoint ! exch round dup //.stdout exch write==only ( ) //print ! exch round dup //.stdout exch write==only ( ) //print ! moveto dup //.stdout exch write==only (\n) //print ! grestore stringwidth rmoveto } odef /show { .showfont .showstring --- 63,129 ---- /copypage { (P\n) //print } odef ! /showpage { copypage erasepage initgraphics } odef % Redefine `show'. ! % Set things up so our output will be in tenths of a point, with origin at ! % lower left. This isolates us from the peculiarities of individual devices. ! /.show.ident.matrix matrix def ! /.show.ident ! { gsave initmatrix 0.1 dup scale .show.ident.matrix currentmatrix grestore ! } def ! /.coord { transform .show.ident itransform } odef ! /.dcoord { dtransform .show.ident idtransform } odef /.showfont ! %old code - This didn't work right for me with all fonts. ! % ! % { 0 currentfont /FontBBox get dup 3 get exch 1 get sub ! % currentfont /FontMatrix get dtransform dtransform ! % exch abs exch abs max round ! % (F ) //print //.stdout exch write==only (\n) //print ! % } odef ! % ! %unfortunately, my way bombs on one of my test files in ! %--%show_continue--(?!). It's from dvi2ps, which molests ! %the fonts in some way. --jgreely ! { (F ) //print ! gsave ! % figure out (roughly) the maximum height of the current ! % font. I picked this string for a mix of ascenders and ! % descenders, with digits tossed in in case of oldstyle ! newpath 0 0 moveto ! (Xyhq69) false charpath flattenpath pathbbox newpath ! exch 4 -1 roll sub 3 1 roll exch sub .dcoord ! round abs //.stdout exch write==only pop ! ( ) //print ! % oddly enough, the "charpath...pathbbox" stuff didn't work ! % right for space in courier ! ( ) stringwidth ! .dcoord pop ! round //.stdout exch write==only ! % ( ) //print ! % //.stdout currentfont /FontName get ! % dup type /nametype eq { =string cvs } if ! % write==only ! (\n) //print ! grestore } odef + /.showstring ! { (S ) //print ! gsave ! currentpoint .coord ! exch round dup //.stdout exch write==only ! ( ) //print ! exch round dup //.stdout exch write==only ! ( ) //print ! moveto dup //.stdout exch write==only ! ( ) //print ! grestore dup stringwidth pop 0 rmoveto ! stringwidth .dcoord pop ! round //.stdout exch write==only ! (\n) //print } odef + /show { .showfont .showstring *************** *** 84,93 **** /widthshow { .showfont ! { 2 copy .show1 eq { 1 index 1 index rmoveto } if } forall pop pop pop ! } /awidthshow { .showfont ! { dup .show1 3 index eq { 4 index 4 index rmoveto } if 2 copy rmoveto } forall --- 140,149 ---- /widthshow { .showfont ! { 2 copy .show1 eq { 1 index 2 index rmoveto } if } forall pop pop pop ! } odef /awidthshow { .showfont ! { dup .show1 3 index eq { 4 index 5 index rmoveto } if 2 copy rmoveto } forall *************** *** 94,98 **** exch neg exch neg rmoveto pop pop pop ! } /kshow { .showfont --- 150,154 ---- exch neg exch neg rmoveto pop pop pop ! } odef /kshow { .showfont *************** *** 107,108 **** --- 163,176 ---- end + + % Bind the operators we just defined, and all the others if we didn't + % do it before. + + bindoperators + NOBIND currentdict systemdict ne and + { systemdict begin bindoperators end } + if + + % Make systemdict read-only if it wasn't already. + + systemdict wcheck { systemdict readonly pop } if diff -rc2N gs241/gs_dps1.ps gs25/gs_dps1.ps *** gs241/gs_dps1.ps Sun Dec 29 11:02:08 1991 --- gs25/gs_dps1.ps Fri May 22 18:08:28 1992 *************** *** 237,241 **** /setshared { pop } odef /setvmthreshold { pop } odef ! /shareddict userdict def /SharedFontDirectory FontDirectory def /vmreclaim { pop } odef --- 237,241 ---- /setshared { pop } odef /setvmthreshold { pop } odef ! /shareddict countdictstack array dictstack 1 get def /SharedFontDirectory FontDirectory def /vmreclaim { pop } odef diff -rc2N gs241/gs_fonts.ps gs25/gs_fonts.ps *** gs241/gs_fonts.ps Mon Apr 20 17:44:16 1992 --- gs25/gs_fonts.ps Tue Aug 11 03:17:56 1992 *************** *** 22,26 **** % Ghostscript fonts have essentially the same contents as Adobe Type 1 fonts, % except that the external form doesn't use eexec encryption. ! % Someday there will be GNU documentation that describes this format. % Until then, you'll have to either get a copy of Adobe's book, or read % the Ghostscript code. The interpreter for Type 1 fonts, which reveals --- 22,26 ---- % Ghostscript fonts have essentially the same contents as Adobe Type 1 fonts, % except that the external form doesn't use eexec encryption. ! % Someday there may be GNU documentation that describes this format. % Until then, you'll have to either get a copy of Adobe's book, or read % the Ghostscript code. The interpreter for Type 1 fonts, which reveals *************** *** 31,70 **** /defaultfontname /Ugly def ! % Put an entry into a dictionary, with automatic expansion. ! /.xput ! { 2 index length 3 index maxlength eq ! { 3 copy pop known not ! { 2 index dup length 3 mul 2 idiv 1 add setmaxlength ! } if ! } if ! put ! } bind def ! ! % Internal procedure to load the font name -> font file name map ! % if it isn't loaded already, and push it on the stack. ! /Fontmap ! { /FontFileMap where ! { /FontFileMap get } ! { (Fontmap) findlibfile not ! { (Can't find ) print print (!\n) print stop } ! if exch pop ! ! FontDirectory maxlength dict exch ! 2 dict begin ! mark exch 2 index exch ! /; ! { % The stack contains a mark, the dictionary, the font name, ! % the file name, and additional information about the font. ! counttomark 3 sub { pop } repeat .xput ! 1 index ! } bind def ! run ! end ! pop pop % pop the mark and the copy of the dictionary ! userdict exch /FontFileMap exch put ! FontFileMap ! } ! ifelse ! } bind def --- 31,49 ---- /defaultfontname /Ugly def ! % Load the font name -> font file name map. ! FontDirectory maxlength dict ! 2 dict begin ! mark 1 index ! /; ! { % The stack contains a mark, the dictionary, the font name, ! % the file or alias name, and possibly additional information ! % about the font. ! counttomark 3 sub { pop } repeat put ! 1 index ! } bind def ! (Fontmap) run ! end ! pop pop % pop the mark and the copy of the dictionary ! userdict exch /Fontmap exch put *************** *** 80,83 **** --- 59,87 ---- + % Define an augmented version of .buildfont1 that inserts UnderlinePosition + % and UnderlineThickness entries in FontInfo if they aren't there already. + % (This works around the incorrect assumption, made by many word processors, + % that these entries are present in the built-in fonts.) + /.buildfont1x + { dup dup /FontInfo get dup dup + /UnderlinePosition known exch /UnderlineThickness known and + { pop pop % entries already present + } + { dup length 2 add dict copy + dup /UnderlinePosition known not + { dup /UnderlinePosition 3 index /FontBBox get + 1 get 2 div put % 1/2 the font descent + } + if + dup /UnderlineThickness known not + { dup /UnderlineThickness 3 index /FontBBox get + dup 3 get exch 1 get sub 20 div put % 1/20 the font height + } + if + 1 index /FontInfo get wcheck not { readonly } if + /FontInfo exch put + } + ifelse .buildfont1 + } bind def % Define definefont. This is a procedure built on an operator that % does all the error checking and key insertion. *************** *** 84,88 **** /.buildfontdict 3 dict /.buildfont0 where { pop dup 0 /.buildfont0 load put } if ! /.buildfont1 where { pop dup 1 /.buildfont1 load put } if /.buildfont3 where { pop dup 3 /.buildfont3 load put } if def --- 88,92 ---- /.buildfontdict 3 dict /.buildfont0 where { pop dup 0 /.buildfont0 load put } if ! /.buildfont1 where { pop dup 1 /.buildfont1x load put } if /.buildfont3 where { pop dup 3 /.buildfont3 load put } if def *************** *** 101,105 **** stopped { count d sub { pop } repeat end /invalidfont signalerror } ! { end dup FontDirectory 4 2 roll .xput } ifelse } odef --- 105,109 ---- stopped { count d sub { pop } repeat end /invalidfont signalerror } ! { end dup FontDirectory 4 2 roll put } ifelse } odef *************** *** 272,275 **** --- 276,282 ---- /.loadfont % .loadfont -> { mark exch systemdict begin + % We really would just like systemdict on the stack, + % but fonts produced by Fontographer require a writable dictionary.... + userdict begin DISKFONTS { .loadfontdict begin } if % We can't just use `run', because we want to check for *************** *** 279,283 **** { false setpacking { dup read not { -1 } if ! 2 copy unread 16#80 eq { /PFBDecode filter } if cvx exec } stopped % split up `execute' --- 286,290 ---- { false setpacking { dup read not { -1 } if ! 2 copy unread 16#80 eq { false /PFBDecode filter } if cvx exec } stopped % split up `execute' *************** *** 286,290 **** } { { dup read not { -1 } if ! 2 copy unread 16#80 eq { /PFBDecode filter } if cvx exec } execute --- 293,297 ---- } { { dup read not { -1 } if ! 2 copy unread 16#80 eq { false /PFBDecode filter } if cvx exec } execute *************** *** 292,296 **** ifelse DISKFONTS { end } if ! end cleartomark } bind def --- 299,303 ---- ifelse DISKFONTS { end } if ! end end cleartomark } bind def *************** *** 297,369 **** % Define findfont so it tries to load a font if it's not found. /findfont ! { ! % If the key is a string, convert it to a name for lookup. ! dup type /stringtype eq { cvn } if ! ! % If the font isn't in FontDirectory already, load it. ! dup FontDirectory exch known ! { FontDirectory exch get } ! { dup % save the font name on the stack ! % Push the font name -> font file name map on the stack, ! % loading it if necessary. ! Fontmap ! ! % Read the file name from the map. ! % (The stack contains the font name and the font file map.) ! 1 index known not ! { QUIET not ! { (Substituting ) print defaultfontname cvx =only ! ( for unknown font ) print == flush ! } { pop } ifelse ! pop defaultfontname findfont ! } ! { dup Fontmap exch get ! % If we can't find the file, substitute for the font. ! findlibfile ! { DISKFONTS ! { 1 index (r) file ! FontFileDirectory exch 4 index exch .xput ! } ! if ! QUIET not ! { (Loading ) print 2 index =only ! ( font from ) print exch print (... ) print flush } ! { exch pop } ! ifelse exch pop ! .loadfont ! QUIET not ! { vmstatus 3 { =only ( ) print } repeat ! (done.\n) print flush ! } if ! % Check to make sure the font was actually loaded. ! dup FontDirectory exch known ! { findfont ! } ! { (Loading ) print cvx =only ! ( font failed, substituting )print defaultfontname cvx =only ! (.\n) print flush ! defaultfontname findfont ! } ! ifelse ! } ! { 1 index defaultfontname eq ! { (Can't find default font!\n) print ! pop pop NullFont ! } ! { (Can't find font file ) print print ! (, substituting ) print defaultfontname cvx =only ! (.\n) print flush ! pop pop defaultfontname findfont ! } ! ifelse ! } ! ifelse } ifelse ! } ifelse } odef % bind def --- 304,386 ---- % Define findfont so it tries to load a font if it's not found. /findfont ! { % Since PostScript has no concept of goto, or even blocks with ! % exits, we use a loop as a way to get an exitable scope. ! % The loop is never executed more than twice. ! { ! dup type /nametype ne % Convert the key to a name for lookup. ! { cvn } if ! ! dup FontDirectory exch known % Already loaded? ! { FontDirectory exch get exit } ! if ! ! dup Fontmap exch known not % Unknown font name. ! { dup defaultfontname eq ! { (Default font ) print cvx =only ! ( not found in Fontmap! Giving up.\n) print flush ! 1 .quit ! } if ! QUIET not ! { (Substituting ) print defaultfontname cvx =only ! ( for unknown font ) print dup == flush ! } if ! pop defaultfontname findfont exit } ! if ! dup Fontmap exch get ! % Check for a font alias. ! dup type /nametype eq ! { findfont ! FontDirectory 2 index 2 index put ! exch pop exit ! } ! if ! ! % If we can't find the file, substitute for the font. ! findlibfile ! { % Stack: fontname fontfilename fontfile ! DISKFONTS ! { 1 index (r) file ! FontFileDirectory exch 4 index exch put } + if + QUIET not + { (Loading ) print 2 index =only + ( font from ) print exch print (... ) print flush } + { exch pop } ifelse + .loadfont + QUIET not + { vmstatus 3 { =only ( ) print } repeat + (done.\n) print flush + } if + % Check to make sure the font was actually loaded. + dup FontDirectory exch known { findfont exit } if + + (Loading ) print cvx =only + ( font failed, substituting ) print defaultfontname cvx =only + (.\n) print flush + defaultfontname findfont exit + } + if + + % findlibfile failed, substitute the default font. + % Stack: fontname fontfilename + (Can't find font file ) print print + dup defaultfontname eq + { ( for default font \() print cvx =only + (\)! Giving up.\n) print flush 1 .quit + } + { ( for font ) print cvx =only + (, substituting ) print defaultfontname cvx =only + (.\n) print flush + defaultfontname findfont + } + ifelse + exit ! } loop % end of loop } odef % bind def diff -rc2N gs241/gs_init.ps gs25/gs_init.ps *** gs241/gs_init.ps Tue Apr 21 05:22:08 1992 --- gs25/gs_init.ps Wed Aug 19 00:55:52 1992 *************** *** 24,38 **** currentdict /DEBUG known /DEBUG exch def /VMDEBUG ! DEBUG {{print vmstatus pop ( ) cvs print pop ( ) print systemdict length ( ) cvs print (\n) print flush}} {{pop}} ifelse def - currentdict /ASCIIOUT known /ASCIIOUT exch def currentdict /DISKFONTS known /DISKFONTS exch def ! currentdict /NODISPLAY known not /DISPLAYING exch def ! currentdict /NOBIND known { /.bind /bind load def /bind { } def } if currentdict /NOCACHE known /NOCACHE exch def currentdict /NOPAUSE known /NOPAUSE exch def ! currentdict /QUIET known ASCIIOUT or /QUIET exch def currentdict /WRITESYSTEMDICT known /WRITESYSTEMDICT exch def --- 24,45 ---- currentdict /DEBUG known /DEBUG exch def /VMDEBUG ! DEBUG {{print ( ) print vmstatus pop ( ) cvs print pop ( ) print systemdict length ( ) cvs print (\n) print flush}} {{pop}} ifelse def currentdict /DISKFONTS known /DISKFONTS exch def ! currentdict /ESTACKPRINT known /ESTACKPRINT exch def ! currentdict /NOBIND known /NOBIND exch def ! /.bind /bind load def ! NOBIND { /bind { } def } if currentdict /NOCACHE known /NOCACHE exch def + currentdict /NODISPLAY known not /DISPLAYING exch def currentdict /NOPAUSE known /NOPAUSE exch def ! currentdict /OUTPUTFILE known % obsolete ! { /OutputFile /OUTPUTFILE load def ! currentdict /OUTPUTFILE undef ! } if ! currentdict /QUIET known /QUIET exch def ! currentdict /SAFER known /SAFER exch def currentdict /WRITESYSTEMDICT known /WRITESYSTEMDICT exch def *************** *** 46,54 **** % Note that the dictionary stack only has 1 element at this point! /systemdict currentdict def ! /userdict 200 dict def ! userdict begin % 2 elements now systemdict begin ! (START ) VMDEBUG % Define true and false. --- 53,65 ---- % Note that the dictionary stack only has 1 element at this point! /systemdict currentdict def ! % Figure out whether we have 2 or 3 permanent dictionaries. ! 0 dict begin ! 0 dict begin ! cleardictstack ! currentdict dup 200 setmaxlength % userdict systemdict begin + /userdict exch def ! (START) VMDEBUG % Define true and false. *************** *** 84,96 **** userdict /.echo.mode true put /echo {dup /.echo.mode exch store .echo} odef - % .eexec - /.eexec - { exch 55665 .filtereexecDecode - cvx systemdict begin exch begin stopped end end - $error /newerror get and {handleerror} if - } bind def /eexec ! { systemdict .eexec ! } odef /executive { { prompt (%statementedit) (r) file --- 95,102 ---- userdict /.echo.mode true put /echo {dup /.echo.mode exch store .echo} odef /eexec ! { 55665 .filtereexecDecode ! cvx systemdict begin stopped end {stop} if ! } bind def /executive { { prompt (%statementedit) (r) file *************** *** 105,111 **** pop pop pop setmatrix initclip} odef % The "revision" is the Ghostscript release number x 100 + the sub-release. ! /gsrevision 241 def /gsrevisiondate ! (4/21/92) def /handleerror {errordict /handleerror get exec} bind def --- 111,117 ---- pop pop pop setmatrix initclip} odef % The "revision" is the Ghostscript release number x 100 + the sub-release. ! /gsrevision 250 def /gsrevisiondate ! (8/18/92) def /handleerror {errordict /handleerror get exec} bind def *************** *** 117,120 **** --- 123,128 ---- /initmatrix {.tempmatrix defaultmatrix setmatrix} odef + /languagelevel + 1 def /matrix {6 array identmatrix} odef /prompt {flush flushpage *************** *** 157,173 **** % Provide semi-fake but usable definitions for % the color PostScript extensions (except for colorimage, ! % which is actually implemented as an operator). ! /setcmykcolor { ! 1 exch sub dup dup % C, M, Y, S, S, S ! 6 -1 roll 1 exch sub mul % M, Y, S, S, red ! exch 5 -1 roll 1 exch sub mul % Y, S, red, green ! 4 -2 roll exch 1 exch sub mul % red, green, blue ! setrgbcolor ! } odef ! /currentcmykcolor { ! currentrgbcolor ! 3 { 1 exch sub 3 1 roll } repeat ! 0 ! } odef /setblackgeneration { pop --- 165,171 ---- % Provide semi-fake but usable definitions for % the color PostScript extensions (except for colorimage, ! % which is actually implemented as an operator, and ! % setcmykcolor and currentcmykcolor, which must be operators ! % to interact properly with setcolor and currentcolor). /setblackgeneration { pop *************** *** 180,184 **** } odef /currentundercolorremoval { ! {} } odef /setcolorscreen { --- 178,182 ---- } odef /currentundercolorremoval { ! {pop 0} } odef /setcolorscreen { *************** *** 196,199 **** --- 194,199 ---- /ASCIIHexEncode /.filterASCIIHexEncode /ASCIIHexDecode /.filterASCIIHexDecode + /CCITTFaxEncode /.filterCCITTFaxEncode + /CCITTFaxDecode /.filterCCITTFaxDecode /eexecDecode /.filtereexecDecode /LZWEncode /.filterLZWEncode *************** *** 228,232 **** /gssetresolution { 2 array astore mark exch /HWResolution exch ! currentdevice copy putdeviceprops setdevice } bind def --- 228,232 ---- /gssetresolution { 2 array astore mark exch /HWResolution exch ! currentdevice copydevice putdeviceprops setdevice } bind def *************** *** 334,338 **** stopped { (Can't find initialization file ) print ! .currentfilename = flush 1 .quit } if exch pop cvx stopped --- 334,340 ---- stopped { (Can't find initialization file ) print ! .currentfilename ! /== where { pop == } { = } ifelse ! flush 1 .quit } if exch pop cvx stopped *************** *** 345,350 **** /run /run0 load def ! % If the user asked for ASCII output, read in the patches now. ! ASCIIOUT { (gs_2asc.ps) run } if % Create the error handling machinery. --- 347,362 ---- /run /run0 load def ! % If we want a "safer" system, disable some obvious ways to cause havoc. ! SAFER ! { /file ! { dup (r) eq ! { file } ! { /invalidfileaccess signalerror } ! ifelse ! } bind odef ! /renamefile { /invalidfileaccess signalerror } odef ! /deletefile { /invalidfileaccess signalerror } odef ! } ! if % Create the error handling machinery. *************** *** 409,413 **** } if currentdict /estack known ! { (\nExecution stack:\n ) print estack { ( ) print =only } forall } if currentdict /dstack known --- 421,426 ---- } if currentdict /estack known ! { (\nExecution stack:\n ) print ! estack { ( ) print ESTACKPRINT { ==only } { =only } ifelse } forall } if currentdict /dstack known *************** *** 510,514 **** /write==only exch def ! (END PROCS ) VMDEBUG % Define the font directory. --- 523,527 ---- /write==only exch def ! (END PROCS) VMDEBUG % Define the font directory. *************** *** 616,620 **** end ! (END FONTDIR/ENCS ) VMDEBUG % Construct a dictionary of all available devices. --- 629,633 ---- end ! (END FONTDIR/ENCS) VMDEBUG % Construct a dictionary of all available devices. *************** *** 631,635 **** $error /newerror false put % remove error indication ! (END DEVS ) VMDEBUG % Define statusdict, for the benefit of programs --- 644,648 ---- $error /newerror false put % remove error indication ! (END DEVS) VMDEBUG % Define statusdict, for the benefit of programs *************** *** 637,664 **** (gs_statd.ps) run ! (END STATD ) VMDEBUG % Load the initialization files for optional features. systemdict /INITFILES known ! { INITFILES { run } forall } if - % Establish a default upper limit in the character cache, - % namely, 10 times the average expected character size. - mark - cachestatus 5 index 10 mul 2 index 1 max idiv % bmax, cmax - mark exch dup 10 idiv exch setcacheparams - cleartomark - % Conditionally disable the character cache. - NOCACHE { 1 setcachelimit } if - - (END CONFIG ) VMDEBUG - - % Load the standard font environment. - (gs_fonts.ps) run - - (END GS_FONTS ) VMDEBUG - % Create a null font. This is the initial font. 7 dict dup begin --- 650,666 ---- (gs_statd.ps) run ! (END STATD) VMDEBUG ! ! % Load the standard font environment. ! (gs_fonts.ps) run + (END GS_FONTS) VMDEBUG + % Load the initialization files for optional features. systemdict /INITFILES known ! { INITFILES { dup run VMDEBUG } forall } if % Create a null font. This is the initial font. 7 dict dup begin *************** *** 675,679 **** FontDirectory /NullFont undef ! (END FONTS ) VMDEBUG % Restore the real definition of run. --- 677,681 ---- FontDirectory /NullFont undef ! (END FONTS) VMDEBUG % Restore the real definition of run. *************** *** 682,701 **** % Bind all the operators defined as procedures. ! % Temporarily disable the typecheck error. ! errordict /typecheck get ! errordict /typecheck { pop } put % pop the command ! systemdict ! { dup type /operatortype eq ! { % This might be a real operator, so bind might cause a typecheck, ! % but we've made the error a no-op temporarily. ! bind ! } ! if pop pop ! } forall ! errordict /typecheck 3 -1 roll put ! ! % Close up systemdict. ! end ! WRITESYSTEMDICT not { systemdict readonly pop } if % Define a procedure for skipping over an unneeded section of code. --- 684,702 ---- % Bind all the operators defined as procedures. ! /bindoperators % binds operators in currentdict ! { % Temporarily disable the typecheck error. ! errordict /typecheck get ! errordict /typecheck { pop } put % pop the command ! currentdict ! { dup type /operatortype eq ! { % This might be a real operator, so bind might cause a typecheck, ! % but we've made the error a no-op temporarily. ! .bind % do a real bind even if NOBIND is set ! } ! if pop pop ! } forall ! errordict /typecheck 3 -1 roll put ! } def ! NOBIND not { bindoperators } if % Define a procedure for skipping over an unneeded section of code. *************** *** 721,727 **** --- 722,748 ---- systemdict /DEVICEWIDTH known systemdict /DEVICEHEIGHT known or + systemdict /DEVICEWIDTHPOINTS known or + systemdict /DEVICEHEIGHTPOINTS known or systemdict /DEVICEXRESOLUTION known or systemdict /DEVICEYRESOLUTION known or + systemdict /PAPERSIZE known or not { (%END DEVICE) .skipeof } if + systemdict /PAPERSIZE known + { % Convert the paper size to device dimensions. + true statusdict /.pagetypenames get + { PAPERSIZE eq + { PAPERSIZE load + dup 0 get /DEVICEWIDTHPOINTS exch def + 1 get /DEVICEHEIGHTPOINTS exch def + pop false exit + } + if + } + forall + { (Unknown paper size: ) print PAPERSIZE ==only (.\n) print + } + if + } + if % Adjust the device parameters per the command line. getdeviceprops dicttomark begin *************** *** 756,761 **** } if /DEVICEWIDTH where ! { pop /dw DEVICEWIDTH def } if /DEVICEHEIGHT where --- 777,784 ---- } if + % Check for device sizes specified in pixels. /DEVICEWIDTH where ! { pop /dw DEVICEWIDTH def ! } if /DEVICEHEIGHT where *************** *** 763,766 **** --- 786,798 ---- } if + % Check for device sizes specified in points. + /DEVICEWIDTHPOINTS where + { pop /dw DEVICEWIDTHPOINTS dxres mul 72 div cvi def + } + if + /DEVICEHEIGHTPOINTS where + { pop /dh DEVICEHEIGHTPOINTS dyres mul 72 div cvi def + } + if mark /HWSize [ dw dh ] /HWResolution [ dxres dyres ] /InitialMatrix dmat *************** *** 768,775 **** end end %END DEVICE ! systemdict /OUTPUTFILE known ! { mark /OutputFile OUTPUTFILE 4 -1 roll putdeviceprops ! } ! if setdevice % does an erasepage %END DISPLAYING --- 800,814 ---- end end %END DEVICE ! mark ! systemdict /BufferSpace known ! { /BufferSpace BufferSpace /MaxBitmap BufferSpace ! } if ! systemdict /OutputFile known ! { /OutputFile OutputFile ! } if ! counttomark dup 0 ne ! { 2 add -1 roll putdeviceprops } ! { pop pop } ! ifelse setdevice % does an erasepage %END DISPLAYING *************** *** 776,781 **** 1 setflat % initgraphics doesn't set this ! { } settransfer % ditto 72 72 dtransform abs exch abs min % min(|dpi x|,|dpi y|) dup 150 lt systemdict /DITHERPPI known not and --- 815,837 ---- 1 setflat % initgraphics doesn't set this ! ! (END DEVICE) VMDEBUG ! ! % Establish a default upper limit in the character cache, ! % namely, enough room for a 1/4" x 1/4" character at the resolution ! % of the default device. ! mark ! 18 18 dtransform % 1/4" x 1/4" ! exch abs cvi 31 add 32 idiv 4 mul % X raster ! exch abs cvi mul % Y ! dup 10 idiv exch ! setcacheparams ! % Conditionally disable the character cache. ! NOCACHE { 1 setcachelimit } if ! ! (END CONFIG) VMDEBUG + % Establish an appropriate halftone screen. + 72 72 dtransform abs exch abs min % min(|dpi x|,|dpi y|) dup 150 lt systemdict /DITHERPPI known not and *************** *** 801,818 **** 32 B2 12 92 3A BA 1A 9A 30 B0 10 90 38 B8 18 98 F2 72 D2 52 FA 7A DA 5A F0 70 D0 50 F8 78 D8 58 ! > exch get 256 div } bind } ! { % Hi-res device, use dot spot function ! % The following 'Niksula dither' was contributed by Hannu Aronsson ! % (haa@cs.hut.fi). It is a better dither for most hi-res printers. ! % 32.5 is the best value of DITHERPPI for the 400 dpi Sony NWP533 ! % printer. ! pop systemdict /DITHERPPI known { DITHERPPI } { 32.5 } ifelse ! 0 ! { exch abs exch abs 2 copy le { exch } if ! exch 1 sub dup mul exch dup mul add 1 exch sub ! } bind ! } ifelse ! setscreen initgraphics % The interpreter relies on there being at least 2 entries --- 857,891 ---- 32 B2 12 92 3A BA 1A 9A 30 B0 10 90 38 B8 18 98 F2 72 D2 52 FA 7A DA 5A F0 70 D0 50 F8 78 D8 58 ! > exch get 256 div } % screen ! { } % transfer ! true % strokeadjust ! } ! { % Hi-res device, use 45 degree dot spot function. ! % 46 seems to be a good frequency value for printers ! % between 200 and 400 DPI. We set the frequency low enough ! % that we can be guaranteed at least a 4x4 pixel cell. ! systemdict /DITHERPPI known { DITHERPPI } { 46 } ifelse ! exch 4.01 div min ! 45 ! { dup mul exch dup mul add 1 exch sub ! } % screen ! % Set the transfer function to lighten up the grays. ! % We correct at the high end so that very light grays ! % don't disappear completely if they darken <1 screen pixel. ! { sqrt dup dup 0.9375 gt exch 1 lt and % > 15/16 ! { currentscreen pop pop ! gsave initmatrix 72 exch div dup dtransform grestore ! cvi exch cvi mul abs % # of pixels in halftone cell ! 1 sub % tweak to avoid boundary ! 1 exch div 1 exch sub min ! } ! if ! } ! false % strokeadjust } ! ifelse ! 5 -3 roll bind setscreen ! exch settransfer ! setstrokeadjust initgraphics % The interpreter relies on there being at least 2 entries *************** *** 828,832 **** false setpacking ! (END INIT ) VMDEBUG QUIET not { (done.\n) print flush } if --- 901,909 ---- false setpacking ! % Close up systemdict. ! end ! WRITESYSTEMDICT not { systemdict readonly pop } if ! ! (END INIT) VMDEBUG QUIET not { (done.\n) print flush } if diff -rc2N gs241/gs_lev2.ps gs25/gs_lev2.ps *** gs241/gs_lev2.ps Tue Apr 7 16:37:22 1992 --- gs25/gs_lev2.ps Mon Jun 15 17:30:56 1992 *************** *** 21,24 **** --- 21,29 ---- % When this is run, systemdict is still writable. + % ------ Miscellaneous ------ % + + % We aren't fully Level 2 compatible yet! + %/languagelevel 2 def + % ------ Painting ------ % *************** *** 26,38 **** % do any caching. /execform ! { dup /Implementation known not ! { dup /FormType get 1 ne { /rangecheck signalerror } if ! dup /Implementation null put readonly } if ! gsave dup /Matrix get concat ! dup /BBox get aload pop ! exch 3 index sub exch 2 index sub rectclip ! dup /PaintProc get exec ! grestore ! } bind def % ------ Resources ------ % --- 31,60 ---- % do any caching. /execform ! { dup /Implementation known not ! { dup /FormType get 1 ne { /rangecheck signalerror } if ! dup /Implementation null put readonly ! } if ! gsave dup /Matrix get concat ! dup /BBox get aload pop ! exch 3 index sub exch 2 index sub rectclip ! dup /PaintProc get exec ! grestore ! } odef ! ! % Recognize the dictionary form of image and imagemask. ! ! /image ! { dup type /dicttype eq { .dictimage } { image } ifelse ! } bind odef % bind now to incorporate old image ! ! /imagemask ! { dup type /dicttype eq { .dictimagemask } { imagemask } ifelse ! } bind odef % bind now to incorporate old imagemask ! ! % ------ Virtual memory ------ % ! ! /currentglobal /currentshared load def ! /gcheck /scheck load def ! /globaldict /shareddict load def % ------ Resources ------ % *************** *** 185,189 **** /FormType {1} /HalftoneType {} ! /ImageType {} /PatternType {} counttomark 2 idiv --- 207,211 ---- /FormType {1} /HalftoneType {} ! /ImageType {1} /PatternType {} counttomark 2 idiv *************** *** 217,230 **** % Complete the Font category. ! % THIS IMPLEMENTATION IS VERY TENTATIVE. /Font /Category findresource begin ! /olddefinefont /definefont load def ! /oldfindfont /findfont load def /DefineResource ! { 2 copy olddefinefont exch 2 copy ! Instances 3 1 roll put exch pop } bind def /FindResource ! { oldfindfont } bind def end --- 239,254 ---- % Complete the Font category. ! % INCOMPLETE. /Font /Category findresource begin ! /..definefont /definefont load def ! /..findfont /findfont load def /DefineResource ! { 2 copy ..definefont exch pop 2 copy ! Instances 3 1 roll put exch pop ! } bind def /FindResource ! { ..findfont ! } bind def end diff -rc2N gs241/gs_statd.ps gs25/gs_statd.ps *** gs241/gs_statd.ps Thu Aug 29 17:37:56 1991 --- gs25/gs_statd.ps Sat Aug 15 08:35:32 1992 *************** *** 1,3 **** ! % Copyright (C) 1989, 1990, 1991 Aladdin Enterprises. All rights reserved. % Distributed by Free Software Foundation, Inc. % --- 1,3 ---- ! % Copyright (C) 1989-1992 Aladdin Enterprises. All rights reserved. % Distributed by Free Software Foundation, Inc. % *************** *** 18,48 **** % copies. ! % This file provides a dummy 'statusdict' and 'serverdict', ! % and a few of the other LaserWriter operators, for the benefit of ! % PostScript programs that think they are running on a LaserWriter. systemdict begin - % Define various paper formats. These are mostly dummies for now. - % Only letter, note, and legal are defined in the Adobe manual. - - /letter {statusdict begin 0 setpagetype end} def - /note {statusdict begin 1 setpagetype end} def - - /11x17 {} def % 11x17 portrait - /a3 {} def - /a4 {} def - /a5 {} def - /a6 {} def - /b4 {} def - /flsa {} def - /flse {} def - /halfletter {} def - /ledger {} def % 11x17 landscape - /legal {} def - /statusdict 80 dict def /serverdict 4 dict def end --- 18,49 ---- % copies. ! % This file provides statusdict, serverdict, and assorted LaserWriter ! % operators, mostly for the benefit of poorly designed PostScript programs ! % that 'know' they are running on a LaserWriter. systemdict begin /statusdict 80 dict def /serverdict 4 dict def + % Define various paper formats. + % Only letter, note, and legal are defined in the Adobe manual. + % These procedures are also accessed as data structures during initialization, + % so the page dimensions must be the first two elements of the procedure. + + /letter {612 792 //statusdict begin .setpagesize end} def + /note {540 720 //statusdict begin .setpagesize end} def + /legal {612 1008 //statusdict begin .setpagesize end} def + /a3 {842 1190 //statusdict begin .setpagesize end} def + /a4 {595 842 //statusdict begin .setpagesize end} def + /a5 {421 595 //statusdict begin .setpagesize end} def + /a6 {297 421 //statusdict begin .setpagesize end} def + /b4 {709 1002 //statusdict begin .setpagesize end} def + /flsa {612 936 //statusdict begin .setpagesize end} def % U.S. foolscap + /flse {612 936 //statusdict begin .setpagesize end} def % European foolscap + /halfletter {396 612 //statusdict begin .setpagesize end} def + /11x17 {792 1224 //statusdict begin .setpagesize end} def % 11x17 portrait + /ledger {1224 792 //statusdict begin .setpagesize end} def % 11x17 landscape + end *************** *** 49,52 **** --- 50,60 ---- statusdict begin + % Define the pagetype values for the known page formats. + % The values for all but letter and note are arbitrary. + /.pagetypenames + { /letter /note /legal /a3 /a4 /a5 /a6 /b4 + /flsa /flse /halfletter /11x17 /ledger + } cvlit readonly def + %%%%%% The following items were suggested by a user as useful. *************** *** 122,126 **** /setmargins {statusdict begin /.leftmargin exch def /.topmargin exch def end} def ! /setpagetype {statusdict exch /pagetype exch put} def /setpassword {exch checkpassword --- 130,139 ---- /setmargins {statusdict begin /.leftmargin exch def /.topmargin exch def end} def ! /setpagetype ! { statusdict begin ! dup .pagetypenames exch get systemdict exch get exec ! /pagetype exch def ! end ! } def /setpassword {exch checkpassword *************** *** 134,137 **** --- 147,158 ---- /waittimeout 300 def + /.setpagesize + { mark /HWSize [ + currentdevice /HWResolution gsgetdeviceprop aload pop + 5 index mul 72 div cvi exch + 6 index mul 72 div cvi exch + ] currentdevice putdeviceprops pop pop pop + initmatrix initclip erasepage + } bind def /.password 0 def /.timeouts [0 60 30] def diff -rc2N gs241/gsaddmod.bat gs25/gsaddmod.bat *** gs241/gsaddmod.bat Mon Nov 4 03:11:24 1991 --- gs25/gsaddmod.bat Wed Jun 10 03:28:02 1992 *************** *** 1 **** ! @echo @command /c gsaddres %2 %3 %4 %5 %6 %7 %8 %9 >>%1.dev --- 1,35 ---- ! @echo off ! if '%3'=='' goto done ! goto %2 ! rem ---------------- dev ---------------- ! :-dev ! echo device_(gs_%3_device)>>%1.d_n ! gsaddmod %1 %2 %4 %5 %6 %7 %8 %9 ! rem ---------------- font ---------------- ! :-font ! echo font_("0.font_%3",gsf_%3,zf_%3)>>%1.d_v ! gsaddmod %1 %2 %4 %5 %6 %7 %8 %9 ! rem ---------------- include ---------------- ! :-include ! echo copy %3.dev _temp_i.bat>>%1.dev ! echo command /c _temp_i.bat>>%1.dev ! gsaddmod %1 %2 %4 %5 %6 %7 %8 %9 ! rem ---------------- lib ---------------- ! :-lib ! echogs -a %1.dev -q echo -s -q %3+ -x 3e3e _temp_.dlb ! gsaddmod %1 %2 %4 %5 %6 %7 %8 %9 ! rem ---------------- obj ---------------- ! :-obj ! for %%x in (%3 %4 %5 %6 %7 %8 %9) do echo %%x+>>%1.d_o ! for %%x in (%3 %4 %5 %6 %7 %8 %9) do echo FILE %%x>>%1.d_w ! goto done ! rem ---------------- oper ---------------- ! :-oper ! for %%x in (%3 %4 %5 %6 %7 %8 %9) do echo oper_(%%x_op_defs)>>%1.d_v ! goto done ! rem ---------------- ps ---------------- ! :-ps ! for %%x in (%3 %4 %5 %6 %7 %8 %9) do echo psfile_("%%x.ps")>>%1.d_v ! goto done ! rem - - - - - - - - done - - - - - - - - ! :done diff -rc2N gs241/gsaddres gs25/gsaddres *** gs241/gsaddres Tue Apr 21 05:16:56 1992 --- gs25/gsaddres Fri Jun 26 08:10:28 1992 *************** *** 4,7 **** --- 4,11 ---- echo device_\(gs_${d}_device\) >>_temp_.dh done;; + -font) shift + for d in $*; do + echo font_\(\"0.font_${d}\",gsf_${d},zf_${d}\) >>_temp_.dft + done;; -include) shift for d in $*; do *************** *** 10,18 **** -lib) shift for l in $*; do ! /bin/sh ./echoq -l${l} >>_temp_.dlb done;; -obj) shift for o in $*; do ! /bin/sh ./echoq ${o} >>_temp_.dob done;; -oper) shift --- 14,24 ---- -lib) shift for l in $*; do ! ./echogs -n -q -l${l} >>_temp_.dlb ! ./echogs -x 205c >>_temp_.dlb done;; -obj) shift for o in $*; do ! ./echogs -n ${o} >>_temp_.dob ! ./echogs -x 205c >>_temp_.dob done;; -oper) shift diff -rc2N gs241/gsaddres.bat gs25/gsaddres.bat *** gs241/gsaddres.bat Tue Apr 21 05:16:50 1992 --- gs25/gsaddres.bat *************** *** 1,44 **** - @echo off - goto %1 - rem ---------------- dev ---------------- - :-dev - shift - if '%1'=='' goto done - echo device_(gs_%1_device) >>_temp_.dh - goto -dev - rem ---------------- include ---------------- - :-include - shift - if '%1'=='' goto done - copy _temp_.bat _temp_.dbt - copy %1.dev _temp_.bat - command /c _temp_.bat - copy _temp_.dbt _temp_.bat - goto -include - rem ---------------- lib ---------------- - :-lib - shift - if '%1'=='' goto done - echo %1+ >>_temp_.dlb - goto -lib - rem ---------------- obj ---------------- - :-obj - shift - if '%1'=='' goto done - echo %1+ >>_temp_.dob - echo FILE %1 >>_temp_.dow - goto -obj - rem ---------------- oper ---------------- - :-oper - shift - if '%1'=='' goto done - echo oper_(%1_op_defs) >>_temp_.dop - goto -oper - rem ---------------- ps ---------------- - :-ps - shift - if '%1'=='' goto done - echo psfile_("%1.ps") >>_temp_.dps - goto -ps - rem - - - - - - - - done - - - - - - - - - :done --- 0 ---- diff -rc2N gs241/gsbj.bat gs25/gsbj.bat *** gs241/gsbj.bat Sat Apr 18 04:26:42 1992 --- gs25/gsbj.bat Mon Aug 10 17:28:00 1992 *************** *** 1 **** ! @gs -q -sDEVICE=bj10e -dDISKFONTS -dNOPAUSE -- gslp.ps %1 %2 %3 %4 %5 %6 %7 %8 %9 \ No newline at end of file --- 1 ---- ! @gs -q -sDEVICE=bj10e -r180 -dDISKFONTS -dNOPAUSE -- gslp.ps %1 %2 %3 %4 %5 %6 %7 %8 %9 diff -rc2N gs241/gschar.c gs25/gschar.c *** gs241/gschar.c Wed Apr 8 09:29:36 1992 --- gs25/gschar.c Mon Jul 20 17:23:44 1992 *************** *** 44,51 **** /* Forward declarations */ private int continue_show(P1(gs_show_enum *)); private int continue_show_update(P1(gs_show_enum *)); ! private int show_setup(P3(gs_show_enum *, gs_state *, char *)); ! private int stringwidth_setup(P3(gs_show_enum *, gs_state *, char *)); /* Print the ctm if debugging */ --- 44,53 ---- /* Forward declarations */ + private int continue_kshow(P1(gs_show_enum *)); private int continue_show(P1(gs_show_enum *)); private int continue_show_update(P1(gs_show_enum *)); ! private int show_setup(P3(gs_show_enum *, gs_state *, const char *)); ! private int show_ctm_setup(P1(gs_show_enum *)); ! private int stringwidth_setup(P3(gs_show_enum *, gs_state *, const char *)); /* Print the ctm if debugging */ *************** *** 73,77 **** int gs_show_init(register gs_show_enum *penum, ! gs_state *pgs, char *str) { setup_show(); penum->slow_show = 0; --- 75,79 ---- int gs_show_init(register gs_show_enum *penum, ! gs_state *pgs, const char *str) { setup_show(); penum->slow_show = 0; *************** *** 80,84 **** int gs_show_n_init(register gs_show_enum *penum, ! gs_state *pgs, char *str, uint size) { setup_show_n(); penum->slow_show = 0; --- 82,86 ---- int gs_show_n_init(register gs_show_enum *penum, ! gs_state *pgs, const char *str, uint size) { setup_show_n(); penum->slow_show = 0; *************** *** 89,93 **** int gs_ashow_init(register gs_show_enum *penum, ! gs_state *pgs, floatp ax, floatp ay, char *str) { int code; setup_show(); --- 91,95 ---- int gs_ashow_init(register gs_show_enum *penum, ! gs_state *pgs, floatp ax, floatp ay, const char *str) { int code; setup_show(); *************** *** 98,102 **** int gs_ashow_n_init(register gs_show_enum *penum, ! gs_state *pgs, floatp ax, floatp ay, char *str, uint size) { int code; setup_show_n(); --- 100,104 ---- int gs_ashow_n_init(register gs_show_enum *penum, ! gs_state *pgs, floatp ax, floatp ay, const char *str, uint size) { int code; setup_show_n(); *************** *** 109,113 **** int gs_widthshow_init(register gs_show_enum *penum, ! gs_state *pgs, floatp cx, floatp cy, char chr, char *str) { int code; setup_show(); --- 111,115 ---- int gs_widthshow_init(register gs_show_enum *penum, ! gs_state *pgs, floatp cx, floatp cy, char chr, const char *str) { int code; setup_show(); *************** *** 118,122 **** int gs_widthshow_n_init(register gs_show_enum *penum, ! gs_state *pgs, floatp cx, floatp cy, char chr, char *str, uint size) { int code; setup_show_n(); --- 120,124 ---- int gs_widthshow_n_init(register gs_show_enum *penum, ! gs_state *pgs, floatp cx, floatp cy, char chr, const char *str, uint size) { int code; setup_show_n(); *************** *** 130,134 **** gs_awidthshow_init(register gs_show_enum *penum, gs_state *pgs, floatp cx, floatp cy, char chr, floatp ax, floatp ay, ! char *str) { int code; setup_show(); --- 132,136 ---- gs_awidthshow_init(register gs_show_enum *penum, gs_state *pgs, floatp cx, floatp cy, char chr, floatp ax, floatp ay, ! const char *str) { int code; setup_show(); *************** *** 141,145 **** gs_awidthshow_n_init(register gs_show_enum *penum, gs_state *pgs, floatp cx, floatp cy, char chr, floatp ax, floatp ay, ! char *str, uint size) { int code; setup_show_n(); --- 143,147 ---- gs_awidthshow_n_init(register gs_show_enum *penum, gs_state *pgs, floatp cx, floatp cy, char chr, floatp ax, floatp ay, ! const char *str, uint size) { int code; setup_show_n(); *************** *** 153,157 **** int gs_kshow_init(register gs_show_enum *penum, ! gs_state *pgs, char *str) { int code; if ( pgs->font->FontType == ft_composite) --- 155,159 ---- int gs_kshow_init(register gs_show_enum *penum, ! gs_state *pgs, const char *str) { int code; if ( pgs->font->FontType == ft_composite) *************** *** 164,168 **** int gs_kshow_n_init(register gs_show_enum *penum, ! gs_state *pgs, char *str, uint size) { int code; if ( pgs->font->FontType == ft_composite) --- 166,170 ---- int gs_kshow_n_init(register gs_show_enum *penum, ! gs_state *pgs, const char *str, uint size) { int code; if ( pgs->font->FontType == ft_composite) *************** *** 178,182 **** /* stringwidth[_n] */ int ! gs_stringwidth_init(gs_show_enum *penum, gs_state *pgs, char *str) { setup_show(); return stringwidth_setup(penum, pgs, str); --- 180,184 ---- /* stringwidth[_n] */ int ! gs_stringwidth_init(gs_show_enum *penum, gs_state *pgs, const char *str) { setup_show(); return stringwidth_setup(penum, pgs, str); *************** *** 183,187 **** } int ! gs_stringwidth_n_init(gs_show_enum *penum, gs_state *pgs, char *str, uint size) { setup_show_n(); return stringwidth_setup(penum, pgs, str); --- 185,189 ---- } int ! gs_stringwidth_n_init(gs_show_enum *penum, gs_state *pgs, const char *str, uint size) { setup_show_n(); return stringwidth_setup(penum, pgs, str); *************** *** 190,195 **** /* Common code for stringwidth[_n] */ private int ! stringwidth_setup(gs_show_enum *penum, gs_state *pgs, char *str) ! { int code = show_setup(penum, pgs, str); if ( code < 0 ) return_error(code); penum->stringwidth_flag = 1; --- 192,197 ---- /* Common code for stringwidth[_n] */ private int ! stringwidth_setup(gs_show_enum *penum, gs_state *pgs, const char *str) ! { int code = (penum->slow_show = 0, show_setup(penum, pgs, str)); if ( code < 0 ) return_error(code); penum->stringwidth_flag = 1; *************** *** 205,209 **** int gs_charpath_init(gs_show_enum *penum, gs_state *pgs, ! char *str, int bool) { int code; setup_show(); --- 207,211 ---- int gs_charpath_init(gs_show_enum *penum, gs_state *pgs, ! const char *str, int bool) { int code; setup_show(); *************** *** 215,219 **** int gs_charpath_n_init(gs_show_enum *penum, gs_state *pgs, ! char *str, uint size, int bool) { int code; setup_show_n(); --- 217,221 ---- int gs_charpath_n_init(gs_show_enum *penum, gs_state *pgs, ! const char *str, uint size, int bool) { int code; setup_show_n(); *************** *** 310,313 **** --- 312,317 ---- /* so that the character lines up with the cache. */ gs_translate_to_fixed(pgs, cc->offset.x, cc->offset.y); + /* Set the initial matrix for the cache device. */ + penum->dev_cache_info.initial_matrix = ctm_only(pgs); /* Reset the clipping path to match the metrics. */ clip_box.p.x = clip_box.p.y = 0; *************** *** 335,339 **** int gs_setmetrics(register gs_show_enum *penum, gs_state *pgs, ! gs_point *psbxy, gs_point *pwxy) { if ( penum->width_status != sws_none ) return_error(gs_error_undefined); --- 339,343 ---- int gs_setmetrics(register gs_show_enum *penum, gs_state *pgs, ! const gs_point *psbxy, const gs_point *pwxy) { if ( penum->width_status != sws_none ) return_error(gs_error_undefined); *************** *** 362,369 **** #define show_fast_move(wxy, pgs)\ gx_path_add_rel_point_inline(pgs->path, wxy.x, wxy.y) ! private int show_update(P1(register gs_show_enum *penum)); ! private int show_move(P1(register gs_show_enum *penum)); ! private int show_proceed(P1(register gs_show_enum *penum)); ! private int show_finish(P1(register gs_show_enum *penum)); private int continue_show_update(register gs_show_enum *penum) --- 366,373 ---- #define show_fast_move(wxy, pgs)\ gx_path_add_rel_point_inline(pgs->path, wxy.x, wxy.y) ! private int show_update(P1(gs_show_enum *penum)); ! private int show_move(P1(gs_show_enum *penum)); ! private int show_proceed(P1(gs_show_enum *penum)); ! private int show_finish(P1(gs_show_enum *penum)); private int continue_show_update(register gs_show_enum *penum) *************** *** 378,381 **** --- 382,393 ---- { return show_proceed(penum); } + /* For kshow, the CTM may have changed, so we have to reestablish */ + /* the cached values in the enumerator. */ + private int + continue_kshow(register gs_show_enum *penum) + { int code = show_ctm_setup(penum); + if ( code < 0 ) return code; + return show_proceed(penum); + } /* Update position */ *************** *** 437,441 **** /* Check for kerning, but not on the last character. */ if ( penum->do_kern && penum->index < penum->size ) ! { penum->continue_proc = continue_show; return gs_show_kern; } --- 449,453 ---- /* Check for kerning, but not on the last character. */ if ( penum->do_kern && penum->index < penum->size ) ! { penum->continue_proc = continue_kshow; return gs_show_kern; } *************** *** 446,450 **** show_proceed(register gs_show_enum *penum) { register gs_state *pgs = penum->pgs; ! byte *str = penum->str; uint index; cached_fm_pair *pair = 0; --- 458,462 ---- show_proceed(register gs_show_enum *penum) { register gs_state *pgs = penum->pgs; ! const byte *str = penum->str; uint index; cached_fm_pair *pair = 0; *************** *** 499,502 **** --- 511,517 ---- /* Character is not cached, client must render it. */ if ( (code = gs_gsave(pgs)) < 0 ) return code; + /* Reset the in_cachedevice flag, so that a recursive show */ + /* will use the cache properly. */ + pgs->in_cachedevice = 0; /* Set the charpath flag in the graphics context if necessary, */ /* so that fill and stroke will add to the path */ *************** *** 503,506 **** --- 518,522 ---- /* rather than having their usual effect. */ pgs->in_charpath = penum->charpath_flag; + pgs->stroke_adjust = 0; /* per specification */ { gs_fixed_point cpt; gx_path *ppath = pgs->path; *************** *** 512,516 **** cpt.x += pgs->ctm.tx_fixed; cpt.y += pgs->ctm.ty_fixed; ! if ( !penum->stringwidth_flag && !penum->charpath_flag ) { /* Round the translation in the graphics state. */ /* This helps prevent rounding artifacts later. */ --- 528,532 ---- cpt.x += pgs->ctm.tx_fixed; cpt.y += pgs->ctm.ty_fixed; ! if ( !penum->charpath_flag ) { /* Round the translation in the graphics state. */ /* This helps prevent rounding artifacts later. */ *************** *** 588,594 **** /* ------ Internal routines ------ */ ! /* Initialize a show enumerator */ private int ! show_setup(register gs_show_enum *penum, gs_state *pgs, char *str) { int code; gs_font *pfont = pgs->font; --- 604,610 ---- /* ------ Internal routines ------ */ ! /* Initialize a show enumerator. */ private int ! show_setup(register gs_show_enum *penum, gs_state *pgs, const char *str) { int code; gs_font *pfont = pgs->font; *************** *** 595,599 **** penum->pgs = pgs; penum->level = pgs->level; ! penum->str = (byte *)str; /* avoid signed chars */ penum->wchr = no_chr; penum->add = 0; --- 611,615 ---- penum->pgs = pgs; penum->level = pgs->level; ! penum->str = (const byte *)str; /* avoid signed chars */ penum->wchr = no_chr; penum->add = 0; *************** *** 611,614 **** --- 627,643 ---- rfont->data.type0_data.FDepVector[rfont->data.type0_data.Encoding[0]]; } + penum->can_cache = 1; /* show_ctm_setup may reset */ + code = show_ctm_setup(penum); + if ( code < 0 ) return code; + return 0; + } + + /* Initialize the CTM-related parts of a show enumerator. */ + /* We do this both when starting the show operation, */ + /* and when returning from the kshow callout. */ + private int + show_ctm_setup(gs_show_enum *penum) + { gs_state *pgs = penum->pgs; + int code; if ( !pgs->char_tm_valid ) { /* Compute combined transformation */ *************** *** 620,624 **** pgs->char_tm_valid = 1; } ! if ( penum->can_cache = /* no skewing or non-rectangular rotation */ (is_fzero2(pgs->char_tm.xy, pgs->char_tm.yx) || is_fzero2(pgs->char_tm.xx, pgs->char_tm.yy)) ) --- 649,653 ---- pgs->char_tm_valid = 1; } ! if ( penum->can_cache &= /* no skewing or non-rectangular rotation */ (is_fzero2(pgs->char_tm.xy, pgs->char_tm.yx) || is_fzero2(pgs->char_tm.xx, pgs->char_tm.yy)) ) diff -rc2N gs241/gschar.h gs25/gschar.h *** gs241/gschar.h Wed Mar 25 10:05:16 1992 --- gs25/gschar.h Fri May 22 18:13:02 1992 *************** *** 29,46 **** /* one that uses the C convention of null-terminated strings, */ /* and one that supplies a length. */ ! int gs_show_init(P3(gs_show_enum *, gs_state *, char *)), ! gs_show_n_init(P4(gs_show_enum *, gs_state *, char *, uint)), ! gs_ashow_init(P5(gs_show_enum *, gs_state *, floatp, floatp, char *)), ! gs_ashow_n_init(P6(gs_show_enum *, gs_state *, floatp, floatp, char *, uint)), ! gs_widthshow_init(P6(gs_show_enum *, gs_state *, floatp, floatp, char, char *)), ! gs_widthshow_n_init(P7(gs_show_enum *, gs_state *, floatp, floatp, char, char *, uint)), ! gs_awidthshow_init(P8(gs_show_enum *, gs_state *, floatp, floatp, char, floatp, floatp, char *)), ! gs_awidthshow_n_init(P9(gs_show_enum *, gs_state *, floatp, floatp, char, floatp, floatp, char *, uint)), ! gs_kshow_init(P3(gs_show_enum *, gs_state *, char *)), ! gs_kshow_n_init(P4(gs_show_enum *, gs_state *, char *, uint)), ! gs_stringwidth_init(P3(gs_show_enum *, gs_state *, char *)), ! gs_stringwidth_n_init(P4(gs_show_enum *, gs_state *, char *, uint)), ! gs_charpath_init(P4(gs_show_enum *, gs_state *, char *, int)), ! gs_charpath_n_init(P5(gs_show_enum *, gs_state *, char *, uint, int)); /* After setting up the enumeration, all the string-related routines */ --- 29,46 ---- /* one that uses the C convention of null-terminated strings, */ /* and one that supplies a length. */ ! int gs_show_init(P3(gs_show_enum *, gs_state *, const char *)), ! gs_show_n_init(P4(gs_show_enum *, gs_state *, const char *, uint)), ! gs_ashow_init(P5(gs_show_enum *, gs_state *, floatp, floatp, const char *)), ! gs_ashow_n_init(P6(gs_show_enum *, gs_state *, floatp, floatp, const char *, uint)), ! gs_widthshow_init(P6(gs_show_enum *, gs_state *, floatp, floatp, char, const char *)), ! gs_widthshow_n_init(P7(gs_show_enum *, gs_state *, floatp, floatp, char, const char *, uint)), ! gs_awidthshow_init(P8(gs_show_enum *, gs_state *, floatp, floatp, char, floatp, floatp, const char *)), ! gs_awidthshow_n_init(P9(gs_show_enum *, gs_state *, floatp, floatp, char, floatp, floatp, const char *, uint)), ! gs_kshow_init(P3(gs_show_enum *, gs_state *, const char *)), ! gs_kshow_n_init(P4(gs_show_enum *, gs_state *, const char *, uint)), ! gs_stringwidth_init(P3(gs_show_enum *, gs_state *, const char *)), ! gs_stringwidth_n_init(P4(gs_show_enum *, gs_state *, const char *, uint)), ! gs_charpath_init(P4(gs_show_enum *, gs_state *, const char *, int)), ! gs_charpath_n_init(P5(gs_show_enum *, gs_state *, const char *, uint, int)); /* After setting up the enumeration, all the string-related routines */ *************** *** 71,80 **** int gs_show_in_charpath(P1(gs_show_enum *)); /* return charpath flag */ - /* Convert an image to an outline encoding. */ - int gs_type1imagepath(P10(gs_state *, const byte *, int, int, - floatp, floatp, floatp, floatp, byte *, uint)); - /* Font cache and metrics operators */ int gs_setcachedevice(P8(gs_show_enum *, gs_state *, floatp, floatp, floatp, floatp, floatp, floatp)); int gs_setcharwidth(P4(gs_show_enum *, gs_state *, floatp, floatp)); ! int gs_setmetrics(P4(gs_show_enum *, gs_state *, gs_point *, gs_point *)); --- 71,76 ---- int gs_show_in_charpath(P1(gs_show_enum *)); /* return charpath flag */ /* Font cache and metrics operators */ int gs_setcachedevice(P8(gs_show_enum *, gs_state *, floatp, floatp, floatp, floatp, floatp, floatp)); int gs_setcharwidth(P4(gs_show_enum *, gs_state *, floatp, floatp)); ! int gs_setmetrics(P4(gs_show_enum *, gs_state *, const gs_point *, const gs_point *)); diff -rc2N gs241/gscie.c gs25/gscie.c *** gs241/gscie.c Sun Feb 9 05:34:18 1992 --- gs25/gscie.c Sun Jun 21 11:59:50 1992 *************** *** 21,24 **** --- 21,25 ---- /* CIE color algorithms for Ghostscript */ #include "std.h" + #include "gscspace.h" #include "gscie.h" *************** *** 28,42 **** { return (float)value; } ! gs_range3 Range3_default = { {0,1}, {0,1}, {0,1} }; ! gs_float_proc3 Decode3_default = { fp_identity, fp_identity, fp_identity }; ! gs_matrix3 Matrix3_default = { {1,0,0}, {0,1,0}, {0,0,1} }; ! gs_range RangeA_default = {0,1}; ! gs_float_proc DecodeA_default = fp_identity; ! gs_vector3 MatrixA_default = { 1, 1, 1 }; ! gs_vector3 BlackPoint_default = { 0, 0, 0 }; /* Apply procedures to a vector. */ private void ! cie_apply3(gs_vector3 *in, gs_float_proc3 *procs, gs_vector3 *out) { out->u = (*procs->u)(in->u); out->v = (*procs->v)(in->v); --- 29,43 ---- { return (float)value; } ! const gs_range3 Range3_default = { {0,1}, {0,1}, {0,1} }; ! const gs_float_proc3 Decode3_default = { fp_identity, fp_identity, fp_identity }; ! const gs_matrix3 Matrix3_default = { {1,0,0}, {0,1,0}, {0,0,1} }; ! const gs_range RangeA_default = {0,1}; ! const gs_float_proc DecodeA_default = fp_identity; ! const gs_vector3 MatrixA_default = { 1, 1, 1 }; ! const gs_vector3 BlackPoint_default = { 0, 0, 0 }; /* Apply procedures to a vector. */ private void ! cie_apply3(const gs_vector3 *in, const gs_float_proc3 *procs, gs_vector3 *out) { out->u = (*procs->u)(in->u); out->v = (*procs->v)(in->v); *************** *** 46,50 **** /* Multiply a vector by a matrix. */ private void ! cie_mult3(gs_vector3 *in, register gs_matrix3 *mat, gs_vector3 *out) { float u = in->u, v = in->v, w = in->w; out->u = (u * mat->cu.u) + (v * mat->cu.v) + (w * mat->cu.w); --- 47,51 ---- /* Multiply a vector by a matrix. */ private void ! cie_mult3(const gs_vector3 *in, register const gs_matrix3 *mat, gs_vector3 *out) { float u = in->u, v = in->v, w = in->w; out->u = (u * mat->cu.u) + (v * mat->cu.v) + (w * mat->cu.w); *************** *** 55,59 **** /* Invert a matrix. */ private void ! cie_invert3(register gs_matrix3 *in, register gs_matrix3 *out) { /* This is a brute force algorithm; maybe there are better. */ /* We label the array elements */ --- 56,60 ---- /* Invert a matrix. */ private void ! cie_invert3(register const gs_matrix3 *in, register gs_matrix3 *out) { /* This is a brute force algorithm; maybe there are better. */ /* We label the array elements */ *************** *** 105,109 **** ((v) < (r).rmin ? (r).rmin : (v) > (r).rmax ? (r).rmax : (v)) private void ! cie_restrict3(gs_vector3 *in, gs_range3 *range, gs_vector3 *out) { float temp; temp = in->u; out->u = restrict(temp, range->u); --- 106,110 ---- ((v) < (r).rmin ? (r).rmin : (v) > (r).rmax ? (r).rmax : (v)) private void ! cie_restrict3(const gs_vector3 *in, const gs_range3 *range, gs_vector3 *out) { float temp; temp = in->u; out->u = restrict(temp, range->u); *************** *** 114,118 **** /* Decode ABC values to XYZ. */ int ! gs_cie_abc_decode1(gs_vector3 *pabc, gs_vector3 *ptabc, gs_cie_abc *pcie) { cie_restrict3(pabc, &pcie->RangeABC, ptabc); return 0; --- 115,119 ---- /* Decode ABC values to XYZ. */ int ! gs_cie_abc_decode1(const gs_vector3 *pabc, gs_vector3 *ptabc, const gs_cie_abc *pcie) { cie_restrict3(pabc, &pcie->RangeABC, ptabc); return 0; *************** *** 123,129 **** */ int ! gs_cie_abc_decode2(gs_vector3 *ptabc, gs_vector3 *ptlmn, gs_cie_abc *pcie) { cie_mult3(ptabc, &pcie->MatrixABC, ptlmn); ! cie_restrict3(ptlmn, &pcie->RangeLMN, ptlmn); return 0; } --- 124,130 ---- */ int ! gs_cie_abc_decode2(const gs_vector3 *ptabc, gs_vector3 *ptlmn, const gs_cie_abc *pcie) { cie_mult3(ptabc, &pcie->MatrixABC, ptlmn); ! cie_restrict3(ptlmn, &pcie->common.RangeLMN, ptlmn); return 0; } *************** *** 130,138 **** /* * Client: ! cie_apply3(ptlmn, &pcie->DecodeLMN, ptlmn); */ int ! gs_cie_abc_decode3(gs_vector3 *ptlmn, gs_vector3 *pxyz, gs_cie_abc *pcie) ! { cie_mult3(ptlmn, &pcie->MatrixLMN, pxyz); return 0; } --- 131,139 ---- /* * Client: ! cie_apply3(ptlmn, &pcie->common.DecodeLMN, ptlmn); */ int ! gs_cie_abc_decode3(const gs_vector3 *ptlmn, gs_vector3 *pxyz, const gs_cie_abc *pcie) ! { cie_mult3(ptlmn, &pcie->common.MatrixLMN, pxyz); return 0; } *************** *** 140,144 **** /* Decode an A value to XYZ. */ int ! gs_cie_a_decode1(floatp va, float *pta, gs_cie_a *pcie) { *pta = restrict(va, pcie->RangeA); return 0; --- 141,145 ---- /* Decode an A value to XYZ. */ int ! gs_cie_a_decode1(floatp va, float *pta, const gs_cie_a *pcie) { *pta = restrict(va, pcie->RangeA); return 0; *************** *** 149,153 **** */ int ! gs_cie_a_decode2(floatp ta, gs_vector3 *ptlmn, gs_cie_a *pcie) { gs_vector3 lmn; lmn.u = ta * pcie->MatrixA.u; --- 150,154 ---- */ int ! gs_cie_a_decode2(floatp ta, gs_vector3 *ptlmn, const gs_cie_a *pcie) { gs_vector3 lmn; lmn.u = ta * pcie->MatrixA.u; *************** *** 154,158 **** lmn.v = ta * pcie->MatrixA.v; lmn.w = ta * pcie->MatrixA.w; ! cie_restrict3(&lmn, &pcie->RangeLMN, ptlmn); return 0; } --- 155,159 ---- lmn.v = ta * pcie->MatrixA.v; lmn.w = ta * pcie->MatrixA.w; ! cie_restrict3(&lmn, &pcie->common.RangeLMN, ptlmn); return 0; } *************** *** 159,163 **** /* * Client: ! cie_apply3(ptlmn, &pcie->DecodeLMN, ptlmn); */ /* gs_cie_a_decode3 is the same as gs_cie_abc_decode3. */ --- 160,164 ---- /* * Client: ! cie_apply3(ptlmn, &pcie->common.DecodeLMN, ptlmn); */ /* gs_cie_a_decode3 is the same as gs_cie_abc_decode3. */ *************** *** 174,178 **** /* Render CIE colors */ int ! gs_cie_render_colors1(gs_vector3 *pxyz, gs_cie_wbsd *pwbsd, gs_vector3 *ptpqr, gs_cie_wb *points, gs_cie_render *pcie) { cie_mult3(pxyz, &pcie->MatrixPQR, ptpqr); pwbsd->ws.xyz = points->WhitePoint; --- 175,179 ---- /* Render CIE colors */ int ! gs_cie_render_colors1(const gs_vector3 *pxyz, gs_cie_wbsd *pwbsd, gs_vector3 *ptpqr, gs_cie_wb *points, const gs_cie_render *pcie) { cie_mult3(pxyz, &pcie->MatrixPQR, ptpqr); pwbsd->ws.xyz = points->WhitePoint; *************** *** 193,197 **** */ int ! gs_cie_render_colors2(gs_vector3 *ptpqr, gs_vector3 *ptlmn, gs_cie_render *pcie) { gs_vector3 xyzd; cie_mult3(ptpqr, &pcie->MatrixPQR_inverse, &xyzd); --- 194,198 ---- */ int ! gs_cie_render_colors2(const gs_vector3 *ptpqr, gs_vector3 *ptlmn, const gs_cie_render *pcie) { gs_vector3 xyzd; cie_mult3(ptpqr, &pcie->MatrixPQR_inverse, &xyzd); *************** *** 204,208 **** */ int ! gs_cir_render_colors3(gs_vector3 *ptlmn, gs_vector3 *ptabc, gs_cie_render *pcie) { gs_vector3 lmn; cie_restrict3(ptlmn, &pcie->RangeLMN, &lmn); --- 205,209 ---- */ int ! gs_cir_render_colors3(const gs_vector3 *ptlmn, gs_vector3 *ptabc, const gs_cie_render *pcie) { gs_vector3 lmn; cie_restrict3(ptlmn, &pcie->RangeLMN, &lmn); *************** *** 215,219 **** */ int ! gs_cie_render_colors4(gs_vector3 *ptabc, float *colors, gs_cie_render *pcie) { gs_vector3 abc; cie_restrict3(ptabc, &pcie->RangeABC, &abc); --- 216,220 ---- */ int ! gs_cie_render_colors4(const gs_vector3 *ptabc, float *colors, const gs_cie_render *pcie) { gs_vector3 abc; cie_restrict3(ptabc, &pcie->RangeABC, &abc); diff -rc2N gs241/gscie.h gs25/gscie.h *** gs241/gscie.h Sun Feb 9 06:02:50 1992 --- gs25/gscie.h Sun Jun 21 11:59:54 1992 *************** *** 20,23 **** --- 20,24 ---- /* gscie.h */ /* Interface to Ghostscript CIE color algorithms */ + /* (requires gscspace.h) /* ------ Common definitions ------ */ *************** *** 55,63 **** /* ------ Color space dictionaries ------ */ ! /* A CIEBasedABC dictionary. */ ! typedef struct gs_cie_abc_s { ! gs_range3 RangeABC; ! gs_float_proc3 DecodeABC; ! gs_matrix3 MatrixABC; gs_range3 RangeLMN; gs_float_proc3 DecodeLMN; --- 56,61 ---- /* ------ Color space dictionaries ------ */ ! /* Elements common to ABC and A dictionaries. */ ! typedef struct gs_cie_common_s { gs_range3 RangeLMN; gs_float_proc3 DecodeLMN; *************** *** 64,88 **** gs_matrix3 MatrixLMN; gs_cie_wb points; ! } gs_cie_abc; /* A CIEBasedA dictionary. */ ! typedef struct gs_cie_a_s { gs_range RangeA; gs_float_proc DecodeA; gs_vector3 MatrixA; ! gs_range3 RangeLMN; ! gs_float_proc3 DecodeLMN; ! gs_matrix3 MatrixLMN; ! gs_cie_wb points; ! } gs_cie_a; /* Default values for components */ ! extern gs_range3 Range3_default; ! extern gs_float_proc3 Decode3_default; ! extern gs_matrix3 Matrix3_default; ! extern gs_range RangeA_default; ! extern gs_float_proc DecodeA_default; ! extern gs_vector3 MatrixA_default; ! extern gs_vector3 BlackPoint_default; /* ------ Rendering dictionaries ------ */ --- 62,91 ---- gs_matrix3 MatrixLMN; gs_cie_wb points; ! } gs_cie_common; ! ! /* A CIEBasedABC dictionary. */ ! struct gs_cie_abc_s { ! gs_range3 RangeABC; ! gs_float_proc3 DecodeABC; ! gs_matrix3 MatrixABC; ! gs_cie_common common; ! }; /* A CIEBasedA dictionary. */ ! struct gs_cie_a_s { gs_range RangeA; gs_float_proc DecodeA; gs_vector3 MatrixA; ! gs_cie_common common; ! }; /* Default values for components */ ! extern const gs_range3 Range3_default; ! extern const gs_float_proc3 Decode3_default; ! extern const gs_matrix3 Matrix3_default; ! extern const gs_range RangeA_default; ! extern const gs_float_proc DecodeA_default; ! extern const gs_vector3 MatrixA_default; ! extern const gs_vector3 BlackPoint_default; /* ------ Rendering dictionaries ------ */ *************** *** 146,156 **** /* Decode ABC values to XYZ. */ ! extern int gs_cie_abc_decode1(P3(gs_vector3 *pabc, gs_vector3 *ptabc, gs_cie_abc *pcie)); ! extern int gs_cie_abc_decode2(P3(gs_vector3 *ptabc, gs_vector3 *ptlmn, gs_cie_abc *pcie)); ! extern int gs_cie_abc_decode3(P3(gs_vector3 *ptlmn, gs_vector3 *pxyz, gs_cie_abc *pcie)); /* Decode A value to XYZ. */ ! extern int gs_cie_a_decode1(P3(floatp va, float *pta, gs_cie_a *pcie)); ! extern int gs_cie_a_decode2(P3(floatp ta, gs_vector3 *ptlmn, gs_cie_a *pcie)); #define gs_cie_a_decode3(ptlmn, pxyz, pcie) gs_cie_abc_decode3(ptlmn, pxyz, pcie) --- 149,159 ---- /* Decode ABC values to XYZ. */ ! extern int gs_cie_abc_decode1(P3(const gs_vector3 *pabc, gs_vector3 *ptabc, const gs_cie_abc *pcie)); ! extern int gs_cie_abc_decode2(P3(const gs_vector3 *ptabc, gs_vector3 *ptlmn, const gs_cie_abc *pcie)); ! extern int gs_cie_abc_decode3(P3(const gs_vector3 *ptlmn, gs_vector3 *pxyz, const gs_cie_abc *pcie)); /* Decode A value to XYZ. */ ! extern int gs_cie_a_decode1(P3(floatp va, float *pta, const gs_cie_a *pcie)); ! extern int gs_cie_a_decode2(P3(floatp ta, gs_vector3 *ptlmn, const gs_cie_a *pcie)); #define gs_cie_a_decode3(ptlmn, pxyz, pcie) gs_cie_abc_decode3(ptlmn, pxyz, pcie) *************** *** 159,164 **** /* Render CIE colors */ ! extern int gs_cie_render_colors1(P5(gs_vector3 *pxyz, gs_cie_wbsd *pwbsd, gs_vector3 *ppqr, gs_cie_wb *points, gs_cie_render *pcie)); ! extern int gs_cir_render_colors2(P3(gs_vector3 *ptpqr, gs_vector3 *ptlmn, gs_cie_render *pcie)); ! extern int gs_cir_render_colors3(P3(gs_vector3 *ptlmn, gs_vector3 *ptabc, gs_cie_render *pcie)); ! extern int gs_cie_render_colors4(P3(gs_vector3 *ptabc, float *colors, gs_cie_render *pcie)); --- 162,167 ---- /* Render CIE colors */ ! extern int gs_cie_render_colors1(P5(const gs_vector3 *pxyz, gs_cie_wbsd *pwbsd, gs_vector3 *ppqr, gs_cie_wb *points, const gs_cie_render *pcie)); ! extern int gs_cir_render_colors2(P3(const gs_vector3 *ptpqr, gs_vector3 *ptlmn, const gs_cie_render *pcie)); ! extern int gs_cir_render_colors3(P3(const gs_vector3 *ptlmn, gs_vector3 *ptabc, const gs_cie_render *pcie)); ! extern int gs_cie_render_colors4(P3(const gs_vector3 *ptabc, float *colors, const gs_cie_render *pcie)); diff -rc2N gs241/gscolor.c gs25/gscolor.c *** gs241/gscolor.c Thu Feb 27 16:16:30 1992 --- gs25/gscolor.c Fri Jul 17 03:27:02 1992 *************** *** 19,26 **** /* gscolor.c */ ! /* Color and halftone operators for GhostScript library */ #include "memory_.h" #include "gx.h" #include "gserrors.h" #include "gxfixed.h" /* ditto */ #include "gxmatrix.h" /* for gzstate.h */ --- 19,28 ---- /* gscolor.c */ ! /* Color and halftone operators for Ghostscript library */ ! #include "math_.h" #include "memory_.h" #include "gx.h" #include "gserrors.h" + #include "gscspace.h" #include "gxfixed.h" /* ditto */ #include "gxmatrix.h" /* for gzstate.h */ *************** *** 30,33 **** --- 32,48 ---- #include "gzht.h" + /* Map a (non-pattern) color space to the number of components */ + /* in a color drawn from that space. */ + const int gs_color_space_num_components[] = { + 1, /* DeviceGray */ + 3, /* DeviceRGB */ + 4, /* DeviceCMYK */ + 3, /* CIEBasedABC */ + 1, /* CIEBasedA */ + 1, /* Separation */ + 1, /* Indexed */ + -1 /* Pattern -- needs special handling */ + }; + /* Halftone enumeration structure */ struct gs_screen_enum_s { *************** *** 104,111 **** } ! /* currentcolorspace */ int ! gs_currentcolorspace(gs_state *pgs, gs_color_space *pcs) ! { *pcs = (gs_color_space)pgs->color->space; return 0; } --- 119,142 ---- } ! /* setcmykcolor */ ! int ! gs_setcmykcolor(gs_state *pgs, floatp c, floatp m, floatp y, floatp k) ! { floatp s = 1.0 - k; ! int code = gs_setrgbcolor(pgs, (1.0 - c) * s, (1.0 - m) * s, ! (1.0 - y) * s); ! if ( code == 0 ) ! pgs->color->space = (byte)gs_color_space_DeviceCMYK; ! return code; ! } ! ! /* currentcmykcolor */ int ! gs_currentcmykcolor(gs_state *pgs, float pr4[4]) ! { gs_color *pcolor = pgs->color; ! tri_return(max_color_param - pcolor->red, ! max_color_param - pcolor->green, ! max_color_param - pcolor->blue, ! pr4); ! pr4[3] = 0.0; return 0; } *************** *** 227,237 **** /* Set up for halftone sampling */ int gs_screen_init(gs_screen_enum *penum, gs_state *pgs, floatp freq, floatp angle) ! { int cwidth, cheight; int code; ht_bit *order; ! if ( freq < 0 ) return_error(gs_error_rangecheck); /* Convert the frequency to cell width and height */ { float cell_size = 72.0 / freq; --- 258,275 ---- /* Set up for halftone sampling */ + typedef struct rat_s { int num, denom; } rat_t; + private float adjust_screen_angle(P2(floatp, rat_t *)); + /* There may be a fmod function and/or macro defined.... */ + #define fmodu(a, b) ((a) - floor((a) / (b)) * (b)) int gs_screen_init(gs_screen_enum *penum, gs_state *pgs, floatp freq, floatp angle) ! { int cell_width, cell_height; ! int tile_width, tile_height; int code; ht_bit *order; ! rat_t arat; ! float copies; ! if ( freq < 0.1 ) return_error(gs_error_rangecheck); /* Convert the frequency to cell width and height */ { float cell_size = 72.0 / freq; *************** *** 250,263 **** #define abs_round(z) (z < 0 ? -(int)(z) : (int)(z)) /*#define abs_round(z) (z < 0 ? -(int)(z - 0.5) : (int)(z + 0.5))*/ ! cwidth = abs_round(pcwh.x); ! cheight = abs_round(pcwh.y); #undef abs_round } /* Force a halfway reasonable cell size. */ ! if ( cwidth <= 4 ) cwidth = 4; ! if ( cheight <= 4 ) cheight = 4; ! if ( cwidth > max_ushort / cheight ) ! return_error(gs_error_rangecheck); ! order = (ht_bit *)gs_malloc(cwidth * cheight, sizeof(ht_bit), "halftone samples"); if ( order == 0 ) return_error(gs_error_VMerror); --- 288,305 ---- #define abs_round(z) (z < 0 ? -(int)(z) : (int)(z)) /*#define abs_round(z) (z < 0 ? -(int)(z - 0.5) : (int)(z + 0.5))*/ ! cell_width = abs_round(pcwh.x); ! cell_height = abs_round(pcwh.y); #undef abs_round } /* Force a halfway reasonable cell size. */ ! if ( cell_width <= 4 ) cell_width = 4; ! if ( cell_height <= 4 ) cell_height = 4; ! angle = adjust_screen_angle(angle, &arat); ! copies = hypot((float)arat.num, (float)arat.denom); ! tile_width = cell_width * copies; ! tile_height = cell_height * copies; ! if ( tile_width > max_ushort / tile_height ) ! return_error(gs_error_limitcheck); ! order = (ht_bit *)gs_malloc(tile_width * tile_height, sizeof(ht_bit), "halftone samples"); if ( order == 0 ) return_error(gs_error_VMerror); *************** *** 265,271 **** penum->ht.angle = angle; penum->ht.order = order; ! penum->ht.width = cwidth; ! penum->ht.height = cheight; ! penum->ht.order_size = cwidth * cheight; penum->x = penum->y = 0; penum->pgs = pgs; --- 307,313 ---- penum->ht.angle = angle; penum->ht.order = order; ! penum->ht.width = tile_width; ! penum->ht.height = tile_height; ! penum->ht.order_size = tile_width * tile_height; penum->x = penum->y = 0; penum->pgs = pgs; *************** *** 272,291 **** /* The transformation matrix must include normalization to the */ /* interval (-1..1), and rotation by the negative of the angle. */ ! { float xscale = 2.0 / cwidth; ! float yscale = 2.0 / cheight; ! gs_matrix mat; ! gs_make_identity(&mat); ! mat.xx = xscale; ! mat.yy = yscale; ! mat.tx = xscale * 0.5 - 1.0; ! mat.ty = yscale * 0.5 - 1.0; ! if ( (code = gs_matrix_rotate(&mat, -angle, &penum->mat)) < 0 ) ! return code; ! #ifdef DEBUG ! if ( gs_debug['h'] ) ! dprintf8("[h]Screen: w=%d h=%d [%f %f %f %f %f %f]\n", ! cwidth, cheight, penum->mat.xx, penum->mat.xy, ! penum->mat.yx, penum->mat.yy, penum->mat.tx, penum->mat.ty); ! #endif } return 0; --- 314,328 ---- /* The transformation matrix must include normalization to the */ /* interval (-1..1), and rotation by the negative of the angle. */ ! { float xscale = 2.0 / cell_width; ! float yscale = 2.0 / cell_height; ! gs_make_rotation(-angle, &penum->mat); ! penum->mat.xx *= xscale, penum->mat.xy *= xscale; ! penum->mat.yx *= yscale, penum->mat.yy *= yscale; ! penum->mat.tx = -1.0; ! penum->mat.ty = -1.0; ! if_debug8('h', "[h]Screen: %dx%d -> %dx%d [%f %f %f %f]\n", ! cell_width, cell_height, tile_width, tile_height, ! penum->mat.xx, penum->mat.xy, ! penum->mat.yx, penum->mat.yy); } return 0; *************** *** 292,295 **** --- 329,357 ---- } + /* Adjust the angle to one with a rational tangent with */ + /* small numerator and denominator. */ + private float + adjust_screen_angle(floatp fang, rat_t *prat) + { float tang = fmodu(fang, 90) * degrees_to_radians; + int quadrant = (int)fang / 90 % 4; + const rat_t *ptrat; + float best_diff, best_ang; + static const rat_t rattab[9] = + { {0,1}, {1,3}, {1,2}, {2,3}, {1,1}, {3,2}, {2,1}, {3,1}, {1,0} }; + for ( ptrat = rattab, best_diff = M_PI; ptrat->denom != 0; ptrat++ ) + { float rang = atan2((double)ptrat->num, (double)ptrat->denom); + float diff = fabs(tang - rang); + if ( diff < best_diff ) + best_diff = diff, best_ang = rang, *prat = *ptrat; + } + /* If we are in an odd quadrant, swap num and denom. */ + if ( quadrant & 1 ) + { int temp = prat->num; + prat->num = prat->denom; + prat->denom = temp; + } + return best_ang * radians_to_degrees + quadrant * 90; + } + /* Report current point for sampling */ private int gx_screen_finish(P1(gs_screen_enum *)); *************** *** 300,304 **** if ( penum->y >= penum->ht.height ) /* all done */ return gx_screen_finish(penum); ! if ( (code = gs_point_transform((floatp)penum->x, (floatp)penum->y, &penum->mat, &pt)) < 0 ) return code; while ( pt.x < -1.0 ) pt.x += 2.0; --- 362,366 ---- if ( penum->y >= penum->ht.height ) /* all done */ return gx_screen_finish(penum); ! if ( (code = gs_point_transform(penum->x + 0.5, penum->y + 0.5, &penum->mat, &pt)) < 0 ) return code; while ( pt.x < -1.0 ) pt.x += 2.0; diff -rc2N gs241/gscolor.h gs25/gscolor.h *** gs241/gscolor.h Thu Feb 13 02:32:46 1992 --- gs25/gscolor.h Thu Jul 16 17:38:54 1992 *************** *** 1,3 **** ! /* Copyright (C) 1991 Aladdin Enterprises. All rights reserved. Distributed by Free Software Foundation, Inc. --- 1,3 ---- ! /* Copyright (C) 1991, 1992 Aladdin Enterprises. All rights reserved. Distributed by Free Software Foundation, Inc. *************** *** 24,34 **** # define gscolor_INCLUDED - /* Color spaces */ - typedef enum { - gs_color_space_DeviceGray = 0, - gs_color_space_DeviceRGB, - gs_color_space_DeviceCMYK /* not used yet */ - } gs_color_space; - /* Color and gray interface */ typedef struct gs_color_s gs_color; --- 24,27 ---- *************** *** 39,44 **** gs_currenthsbcolor(P2(gs_state *, float [3])), gs_setrgbcolor(P4(gs_state *, floatp, floatp, floatp)), ! gs_currentrgbcolor(P2(gs_state *, float [3])); ! int gs_currentcolorspace(P2(gs_state *, gs_color_space *)); /* Transfer function */ typedef float (*gs_transfer_proc)(P2(gs_state *, floatp)); --- 32,38 ---- gs_currenthsbcolor(P2(gs_state *, float [3])), gs_setrgbcolor(P4(gs_state *, floatp, floatp, floatp)), ! gs_currentrgbcolor(P2(gs_state *, float [3])), ! gs_setcmykcolor(P5(gs_state *, floatp, floatp, floatp, floatp)), ! gs_currentcmykcolor(P2(gs_state *, float [4])); /* Transfer function */ typedef float (*gs_transfer_proc)(P2(gs_state *, floatp)); diff -rc2N gs241/gscolor2.c gs25/gscolor2.c *** gs241/gscolor2.c --- gs25/gscolor2.c Thu Jul 16 17:53:32 1992 *************** *** 0 **** --- 1,72 ---- + /* Copyright (C) 1992 Aladdin Enterprises. All rights reserved. + Distributed by Free Software Foundation, Inc. + + This file is part of Ghostscript. + + Ghostscript is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY. No author or distributor accepts responsibility + to anyone for the consequences of using it or for whether it serves any + particular purpose or works at all, unless he says so in writing. Refer + to the Ghostscript General Public License for full details. + + Everyone is granted permission to copy, modify and redistribute + Ghostscript, but only under the conditions described in the Ghostscript + General Public License. A copy of this license is supposed to have been + given to you along with Ghostscript so you can know your rights and + responsibilities. It should be in a file named COPYING. Among other + things, the copyright notice and this notice must be preserved on all + copies. */ + + /* gscolor2.c */ + /* Level 2 color and halftone operators for Ghostscript library */ + #include "gx.h" + #include "gserrors.h" + #include "gxfixed.h" /* ditto */ + #include "gxmatrix.h" /* for gzstate.h */ + #include "gxdevice.h" /* for gx_color_index */ + #include "gzstate.h" + #include "gzcolor.h" + #include "gscspace.h" + #include "gscolor2.h" + + /* + * NOTE: The only color spaces currently implemented by Ghostscript + * are DeviceGray, DeviceRGB, and DeviceCMYK. This is the module where that + * limitation is enforced, since setcolorspace is the only way that + * any other color space can be made current (other than specialized + * operators such as setpattern.) + */ + + int + gs_setcolorspace(gs_state *pgs, gs_color_space *pcs) + { /****** ONLY IMPLEMENTED FOR Device SPACES ******/ + int code; + switch ( pcs->type ) + { + case gs_color_space_DeviceGray: + code = gs_setgray(pgs, 0.0); + break; + case gs_color_space_DeviceRGB: + code = gs_setrgbcolor(pgs, 0.0, 0.0, 0.0); + break; + case gs_color_space_DeviceCMYK: + code = gs_setcmykcolor(pgs, 0.0, 0.0, 0.0, 1.0); + break; + default: + code = gs_error_undefined; + } + return code; + } + + /* currentcolorspace */ + int + gs_currentcolorspace(const gs_state *pgs, gs_color_space *pcs) + { /****** ONLY IMPLEMENTED FOR Device SPACES ******/ + int num_comp; + pcs->type = (gs_color_space_type)pgs->color->space; + if ( (num_comp = gs_color_space_num_components[(int)pcs->type]) < 0 ) + { /* Uncolored pattern space, consult underlying space. */ + /* NOT IMPLEMENTED YET */ + } + return num_comp; + } diff -rc2N gs241/gscolor2.h gs25/gscolor2.h *** gs241/gscolor2.h --- gs25/gscolor2.h Sun Jun 21 16:22:26 1992 *************** *** 0 **** --- 1,26 ---- + /* Copyright (C) 1992 Aladdin Enterprises. All rights reserved. + Distributed by Free Software Foundation, Inc. + + This file is part of Ghostscript. + + Ghostscript is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY. No author or distributor accepts responsibility + to anyone for the consequences of using it or for whether it serves any + particular purpose or works at all, unless he says so in writing. Refer + to the Ghostscript General Public License for full details. + + Everyone is granted permission to copy, modify and redistribute + Ghostscript, but only under the conditions described in the Ghostscript + General Public License. A copy of this license is supposed to have been + given to you along with Ghostscript so you can know your rights and + responsibilities. It should be in a file named COPYING. Among other + things, the copyright notice and this notice must be preserved on all + copies. */ + + /* gscolor2.h */ + /* Client interface to Level 2 color routines for Ghostscript library */ + /* (requires gscolor.h and gscspace.h) */ + + /* Color and color space */ + int gs_currentcolorspace(P2(const gs_state *, gs_color_space *)); + int gs_setcolorspace(P2(gs_state *, gs_color_space *)); diff -rc2N gs241/gsconfig gs25/gsconfig *** gs241/gsconfig Tue Apr 21 04:16:14 1992 --- gs25/gsconfig Mon Jun 1 03:27:58 1992 *************** *** 2,9 **** shift else ! rm -f _temp_.dob _temp_.dlb _temp_.d ! touch _temp_.dob _temp_.dlb _temp_.d rm -f _temp_.dh _temp_.dop _temp_.dps echo '/* This file was automatically generated by Ghostscript (gsconfig). */' > _temp_.dh touch _temp_.dop _temp_.dps fi --- 2,10 ---- shift else ! rm -f _temp_.dft _temp_.dob _temp_.dlb _temp_.d ! touch _temp_.dft _temp_.dob _temp_.dlb _temp_.d rm -f _temp_.dh _temp_.dop _temp_.dps echo '/* This file was automatically generated by Ghostscript (gsconfig). */' > _temp_.dh + echo '/* See gconfig.c for documentation. */' >>_temp_.dh touch _temp_.dop _temp_.dps fi *************** *** 14,17 **** --- 15,19 ---- sort <_temp_.dob | uniq >obj.tr mv _temp_.dh gconfig.h + sort <_temp_.dft | uniq >>gconfig.h sort <_temp_.dop | uniq >>gconfig.h mv _temp_.dlb lib.tr diff -rc2N gs241/gsconfig.bat gs25/gsconfig.bat *** gs241/gsconfig.bat Tue Apr 21 04:10:48 1992 --- gs25/gsconfig.bat Tue Aug 11 18:32:56 1992 *************** *** 4,11 **** echo # >_temp_.dow echo /* This file was automatically generated by Ghostscript (gsconfig.bat). */ >_temp_.dh echo /* */ >_temp_.dop - echo /* */ >_temp_.dps echo + >_temp_.dlb ! echo @echo off >_temp_.bat goto top :noinit --- 4,11 ---- echo # >_temp_.dow echo /* This file was automatically generated by Ghostscript (gsconfig.bat). */ >_temp_.dh + echo /* See gconfig.c for documentation. */ >>_temp_.dh echo /* */ >_temp_.dop echo + >_temp_.dlb ! echogs @echo off >_temp_.bat goto top :noinit *************** *** 14,31 **** if '%1'=='' goto done if '%1'=='+' goto nofin ! type %1 >>_temp_.bat shift goto top :done ! command /c _temp_.bat sort <_temp_.dob | uniq >obj.tr sort <_temp_.dow | uniq >objw.tr ! if exist gconfig.h erase gconfig.h ! rename _temp_.dh gconfig.h ! sort <_temp_.dop | uniq >>gconfig.h if exist lib.tr erase lib.tr rename _temp_.dlb lib.tr ! sort <_temp_.dps | uniq >>gconfig.h erase _temp_.d* ! erase _temp_.bat :nofin --- 14,30 ---- if '%1'=='' goto done if '%1'=='+' goto nofin ! copy /b _temp_.bat+%1 >nul shift goto top :done ! command /c _temp_.bat >nul sort <_temp_.dob | uniq >obj.tr sort <_temp_.dow | uniq >objw.tr ! sort <_temp_.dop | uniq >>_temp_.dh if exist lib.tr erase lib.tr rename _temp_.dlb lib.tr ! if exist gconfig.h erase gconfig.h ! rename _temp_.dh gconfig.h erase _temp_.d* ! erase _temp_*.bat :nofin diff -rc2N gs241/gscoord.h gs25/gscoord.h *** gs241/gscoord.h Fri Mar 6 11:06:28 1992 --- gs25/gscoord.h Sat Jul 18 04:29:22 1992 *************** *** 37,38 **** --- 37,45 ---- gs_itransform(P4(gs_state *, floatp, floatp, gs_point *)), gs_idtransform(P4(gs_state *, floatp, floatp, gs_point *)); + + /* Inline versions of some of the transformations */ + #define gs_idtransform_inline(pgs, dx, dy, pt)\ + (is_skewed(&(pgs)->ctm) ? gs_idtransform(pgs, dx, dy, pt) :\ + is_fzero((pgs)->ctm.xx) || is_fzero((pgs)->ctm.yy) ?\ + gs_note_error(gs_error_undefinedresult) :\ + ((pt)->x = (dx) / (pgs)->ctm.xx, (pt)->y = (dy) / (pgs)->ctm.yy, 0)) diff -rc2N gs241/gscrypt1.h gs25/gscrypt1.h *** gs241/gscrypt1.h --- gs25/gscrypt1.h Sun May 10 18:18:56 1992 *************** *** 0 **** --- 1,40 ---- + /* Copyright (C) 1990, 1992 Aladdin Enterprises. All rights reserved. + Distributed by Free Software Foundation, Inc. + + This file is part of Ghostscript. + + Ghostscript is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY. No author or distributor accepts responsibility + to anyone for the consequences of using it or for whether it serves any + particular purpose or works at all, unless he says so in writing. Refer + to the Ghostscript General Public License for full details. + + Everyone is granted permission to copy, modify and redistribute + Ghostscript, but only under the conditions described in the Ghostscript + General Public License. A copy of this license is supposed to have been + given to you along with Ghostscript so you can know your rights and + responsibilities. It should be in a file named COPYING. Among other + things, the copyright notice and this notice must be preserved on all + copies. */ + + /* gscrypt1.h */ + /* Interface to Adobe Type 1 encryption/decryption. */ + + /* Normal public interface */ + typedef ushort crypt_state; + int gs_type1_encrypt(P4(byte *dest, const byte *src, uint len, crypt_state *pstate)); + int gs_type1_decrypt(P4(byte *dest, const byte *src, uint len, crypt_state *pstate)); + + /* Define the encryption parameters and procedures */ + #define crypt_c1 ((ushort)52845) + #define crypt_c2 ((ushort)22719) + #define encrypt_next(ch, state, chvar)\ + chvar = ((ch) ^ (state >> 8)),\ + state = (chvar + state) * crypt_c1 + crypt_c2 + #define decrypt_this(ch, state)\ + ((ch) ^ (state >> 8)) + #define decrypt_next(ch, state, chvar)\ + chvar = decrypt_this(ch, state),\ + decrypt_skip_next(ch, state) + #define decrypt_skip_next(ch, state)\ + state = ((ch) + state) * crypt_c1 + crypt_c2 diff -rc2N gs241/gscspace.h gs25/gscspace.h *** gs241/gscspace.h --- gs25/gscspace.h Thu Jul 16 17:49:22 1992 *************** *** 0 **** --- 1,112 ---- + /* Copyright (C) 1991, 1992 Aladdin Enterprises. All rights reserved. + Distributed by Free Software Foundation, Inc. + + This file is part of Ghostscript. + + Ghostscript is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY. No author or distributor accepts responsibility + to anyone for the consequences of using it or for whether it serves any + particular purpose or works at all, unless he says so in writing. Refer + to the Ghostscript General Public License for full details. + + Everyone is granted permission to copy, modify and redistribute + Ghostscript, but only under the conditions described in the Ghostscript + General Public License. A copy of this license is supposed to have been + given to you along with Ghostscript so you can know your rights and + responsibilities. It should be in a file named COPYING. Among other + things, the copyright notice and this notice must be preserved on all + copies. */ + + /* gscspace.h */ + /* Client interface to color spaces for Ghostscript library */ + + #ifndef gscspace_INCLUDED + # define gscspace_INCLUDED + + /* Color spaces. Note that Level 1 configurations */ + /* support only the Device color spaces. */ + typedef enum { + gs_color_space_DeviceGray = 0, + gs_color_space_DeviceRGB, + gs_color_space_DeviceCMYK, + /* FOLLOWING ARE NOT USED YET */ + gs_color_space_CIEBasedABC, + gs_color_space_CIEBasedA, + gs_color_space_Separation, + gs_color_space_Indexed, + gs_color_space_Pattern + } gs_color_space_type; + /* Map a (non-pattern) color space to the number of components */ + /* in a color drawn from that space. */ + extern const int gs_color_space_num_components[]; + + /* + * Color spaces are complicated because different spaces involve + * different kinds of parameters, as follows: + + Space Space parameters Color parameters + ----- ---------------- ---------------- + DeviceGray (none) 1 real [0-1] + DeviceRGB (none) 3 reals [0-1] + DeviceCMYK (none) 4 reals [0-1] + CIEBasedABC dictionary 3 reals + CIEBasedA dictionary 1 real + Separation name, alt_space, tint_xform 1 real [0-1] + Indexed hival, lookup, base_space 1 int [0-maxval] + Pattern colored: (none) dictionary + uncolored: base_space dictionary + base space params + + */ + + /* Base color spaces (Device and CIE) */ + + typedef struct gs_cie_abc_s gs_cie_abc; + typedef struct gs_cie_a_s gs_cie_a; + #define gs_base_cspace_params\ + gs_cie_abc *abc;\ + gs_cie_a *a + typedef struct gs_base_color_space_s { + gs_color_space_type type; + union { + gs_base_cspace_params; + } params; + } gs_base_color_space; + + /* Non-pattern color spaces (base + Separation + Indexed) */ + + typedef struct gs_separation_params_s { + uint sname; /* BOGUS, should be some other type */ + gs_base_color_space alt_space; + int (*tint_transform)(P2(floatp, float*)); + } gs_separation_params; + typedef struct gs_indexed_params_s { + const byte *lookup; + int hival; + gs_base_color_space base_space; + } gs_indexed_params; + #define gs_non_pattern_cspace_params\ + gs_base_cspace_params;\ + gs_separation_params separation;\ + gs_indexed_params indexed + typedef struct gs_non_pattern_color_space_s { + gs_color_space_type type; + union { + gs_non_pattern_cspace_params; + } params; + } gs_non_pattern_color_space; + + /* General color spaces (including patterns) */ + + typedef struct gs_pattern_params_s { + int has_base_space; + gs_non_pattern_color_space base_space; + } gs_pattern_params; + typedef struct gs_color_space_s { + gs_color_space_type type; + union { + gs_non_pattern_cspace_params; + gs_pattern_params pattern; + } params; + } gs_color_space; + + #endif /* gscspace_INCLUDED */ diff -rc2N gs241/gsdevice.c gs25/gsdevice.c *** gs241/gsdevice.c Tue Apr 7 16:19:02 1992 --- gs25/gsdevice.c Wed Aug 19 00:55:56 1992 *************** *** 110,114 **** /* Get the current device from the graphics state */ gx_device * ! gs_currentdevice(gs_state *pgs) { return pgs->device->info; } --- 110,114 ---- /* Get the current device from the graphics state */ gx_device * ! gs_currentdevice(const gs_state *pgs) { return pgs->device->info; } *************** *** 116,120 **** /* Get the name of a device */ const char * ! gs_devicename(gx_device *dev) { return dev->dname; } --- 116,120 ---- /* Get the name of a device */ const char * ! gs_devicename(const gx_device *dev) { return dev->dname; } *************** *** 136,142 **** } ! /* Cloning an existing device. */ int ! gs_copydevice(gx_device **pnew_dev, gx_device *dev, proc_alloc_t palloc) { register gx_device *new_dev; new_dev = (gx_device *)(*palloc)(1, dev->params_size, "gs_copydevice"); --- 136,142 ---- } ! /* Clone an existing device. */ int ! gs_copydevice(gx_device **pnew_dev, const gx_device *dev, proc_alloc_t palloc) { register gx_device *new_dev; new_dev = (gx_device *)(*palloc)(1, dev->params_size, "gs_copydevice"); *************** *** 153,159 **** /* (2^N or 3*2^N). */ int ! gs_makeimagedevice(gx_device **pnew_dev, gs_matrix *pmat, ! uint width, uint height, byte *colors, int num_colors, proc_alloc_t palloc) ! { gx_device_memory *old_dev; register gx_device_memory *new_dev; byte *bits; --- 153,160 ---- /* (2^N or 3*2^N). */ int ! gs_makeimagedevice(gx_device **pnew_dev, const gs_matrix *pmat, ! uint width, uint height, const byte *colors, int num_colors, ! proc_alloc_t palloc) ! { const gx_device_memory *old_dev; register gx_device_memory *new_dev; byte *bits; *************** *** 201,205 **** /* and, if it has any colors, the six primaries. */ if ( bits_per_pixel <= 8 ) ! { byte *p, *q; int primary_mask = 0; int i; --- 202,207 ---- /* and, if it has any colors, the six primaries. */ if ( bits_per_pixel <= 8 ) ! { const byte *p; ! byte *q; int primary_mask = 0; int i; *************** *** 341,351 **** } - /* Read the native color space of the current device. */ - gs_color_space - gx_device_color_space(gs_state *pgs) - { return (gx_device_has_color(pgs->device->info) ? - gs_color_space_DeviceRGB : gs_color_space_DeviceGray); - } - /* Just set the device without reinitializing. */ /* (For internal use only.) */ --- 343,346 ---- *************** *** 358,362 **** /* with or without padding to a word boundary. */ uint ! gx_device_bytes_per_scan_line(gx_device *dev, int pad) { ulong bits = (ulong)dev->width * dev->color_info.depth; return (pad ? --- 353,357 ---- /* with or without padding to a word boundary. */ uint ! gx_device_bytes_per_scan_line(const gx_device *dev, int pad) { ulong bits = (ulong)dev->width * dev->color_info.depth; return (pad ? *************** *** 365,368 **** --- 360,378 ---- } + /* Adjust the resolution for devices that only have a fixed set of */ + /* geometries, so that the apparent size in inches remains constant. */ + int + gx_device_adjust_resolution(gx_device *dev, + int actual_width, int actual_height) + { double width_ratio = (double)actual_width / dev->width ; + double height_ratio = (double)actual_height / dev->height ; + double ratio = max(width_ratio, height_ratio); + dev->x_pixels_per_inch *= ratio; + dev->y_pixels_per_inch *= ratio; + dev->width = actual_width; + dev->height = actual_height; + return 0; + } + /* ------ The null `device' ------ */ *************** *** 373,377 **** } private int ! null_tile_rectangle(gx_device *dev, gx_bitmap *tile, int x, int y, int w, int h, gx_color_index zero, gx_color_index one, int px, int py) --- 383,387 ---- } private int ! null_tile_rectangle(gx_device *dev, const gx_bitmap *tile, int x, int y, int w, int h, gx_color_index zero, gx_color_index one, int px, int py) *************** *** 379,383 **** } private int ! null_copy_mono(gx_device *dev, byte *data, int dx, int raster, gx_bitmap_id id, int x, int y, int w, int h, gx_color_index zero, gx_color_index one) --- 389,393 ---- } private int ! null_copy_mono(gx_device *dev, const byte *data, int dx, int raster, gx_bitmap_id id, int x, int y, int w, int h, gx_color_index zero, gx_color_index one) *************** *** 440,444 **** int ! gx_default_copy_color(gx_device *dev, unsigned char *data, int data_x, int raster, gx_bitmap_id id, int x, int y, int width, int height) --- 450,454 ---- int ! gx_default_copy_color(gx_device *dev, const byte *data, int data_x, int raster, gx_bitmap_id id, int x, int y, int width, int height) *************** *** 449,453 **** int gx_default_get_bits(gx_device *dev, int y, ! unsigned char *data, unsigned int size, int pad) { return -1; } --- 459,463 ---- int gx_default_get_bits(gx_device *dev, int y, ! byte *data, unsigned int size, int pad) { return -1; } *************** *** 455,459 **** /* Standard device properties */ ! private gs_prop_item props_std[] = { prop_def("HWResolution", prt_float_array), prop_def("HWSize", prt_int_array), --- 465,471 ---- /* Standard device properties */ ! private const gs_prop_item props_std[] = { ! /* Following can be set, but will close and */ ! /* reopen the device if necessary. */ prop_def("HWResolution", prt_float_array), prop_def("HWSize", prt_int_array), *************** *** 469,473 **** }; ! /* Get standard properties */ int gx_default_get_props(register gx_device *dev, register gs_prop_item *plist) --- 481,485 ---- }; ! /* Get standard properties. */ int gx_default_get_props(register gx_device *dev, register gs_prop_item *plist) *************** *** 506,530 **** } ! /* Set standard properties */ int gx_default_put_props(gx_device *dev, gs_prop_item *plist, int count) { gs_prop_item *known[2]; props_extract(plist, count, props_std, 2, known, 1); ! if ( known[0] != 0 ) ! { if ( known[0]->value.a.size != 2 ) ! known[0]->status = pv_typecheck; ! else ! { gs_prop_item *ap = known[0]->value.a.p.v; ! if ( ap[0].value.f <= 0 || ap[1].value.f <= 0 ) ! known[0]->status = pv_rangecheck; ! else ! { dev->x_pixels_per_inch = ap[0].value.f; ! dev->y_pixels_per_inch = ap[1].value.f; ! } ! } ! } if ( known[1] != 0 ) { if ( known[1]->value.a.size != 2 ) ! known[1]->status = pv_typecheck; else { gs_prop_item *ap = known[1]->value.a.p.v; --- 518,536 ---- } ! /* Set standard properties. */ ! /* Note that if the device is open, it will be closed and reopened. */ ! /****** DOESN'T FIND ALL GSTATES THAT REFERENCE THE DEVICE. ******/ int gx_default_put_props(gx_device *dev, gs_prop_item *plist, int count) { gs_prop_item *known[2]; + int reopen; + int code = 0; + gx_device temp_dev; props_extract(plist, count, props_std, 2, known, 1); ! temp_dev = *dev; if ( known[1] != 0 ) { if ( known[1]->value.a.size != 2 ) ! known[1]->status = pv_typecheck, ! code = gs_error_typecheck; else { gs_prop_item *ap = known[1]->value.a.p.v; *************** *** 532,542 **** ap[1].value.i <= 0 || ap[1].value.i > 0x7fff ) ! known[1]->status = pv_rangecheck; else ! { dev->width = ap[0].value.i; ! dev->height = ap[1].value.i; } } } return 0; } --- 538,578 ---- ap[1].value.i <= 0 || ap[1].value.i > 0x7fff ) ! known[1]->status = pv_rangecheck, ! code = gs_error_rangecheck; ! else ! { temp_dev.width = ap[0].value.i; ! temp_dev.height = ap[1].value.i; ! } ! } ! } ! if ( known[0] != 0 ) ! { if ( known[0]->value.a.size != 2 ) ! known[0]->status = pv_typecheck, ! code = gs_error_typecheck; ! else ! { gs_prop_item *ap = known[0]->value.a.p.v; ! if ( ap[0].value.f <= 0 || ap[1].value.f <= 0 ) ! known[0]->status = pv_rangecheck, ! code = gs_error_rangecheck; else ! { temp_dev.x_pixels_per_inch = ap[0].value.f; ! temp_dev.y_pixels_per_inch = ap[1].value.f; } } } + if ( code < 0 ) + return_error(code); + reopen = dev->is_open && (known[0] != 0 || known[1] != 0); + if ( reopen ) + if ( (code = gs_closedevice(dev)) < 0 ) return code; + dev->x_pixels_per_inch = temp_dev.x_pixels_per_inch; + dev->y_pixels_per_inch = temp_dev.y_pixels_per_inch; + dev->width = temp_dev.width; + dev->height = temp_dev.height; + if ( reopen ) + { if ( (code = (*dev->procs->open_device)(dev)) < 0 ) + return_error(code); + dev->is_open = 1; + } return 0; } diff -rc2N gs241/gsdj500.bat gs25/gsdj500.bat *** gs241/gsdj500.bat --- gs25/gsdj500.bat Sun Apr 12 16:48:04 1992 *************** *** 0 **** --- 1 ---- + @gs -q -sDEVICE=djet500 -r300 -dDISKFONTS -dNOPAUSE -- gslp.ps %1 %2 %3 %4 %5 %6 %7 %8 %9 \ No newline at end of file diff -rc2N gs241/gsdps1.c gs25/gsdps1.c *** gs241/gsdps1.c Sat Feb 29 06:20:20 1992 --- gs25/gsdps1.c Fri Apr 24 20:07:00 1992 *************** *** 42,46 **** /* Append a list of rectangles to a path. */ int ! gs_rectappend(gs_state *pgs, gs_rect *pr, uint count) { for ( ; count != 0; count--, pr++ ) { floatp px = pr->p.x, py = pr->p.y, qx = pr->q.x, qy = pr->q.y; --- 42,46 ---- /* Append a list of rectangles to a path. */ int ! gs_rectappend(gs_state *pgs, const gs_rect *pr, uint count) { for ( ; count != 0; count--, pr++ ) { floatp px = pr->p.x, py = pr->p.y, qx = pr->q.x, qy = pr->q.y; *************** *** 62,66 **** /* Clip to a list of rectangles. */ int ! gs_rectclip(gs_state *pgs, gs_rect *pr, uint count) { int code; if ( (code = gs_newpath(pgs)) < 0 || --- 62,66 ---- /* Clip to a list of rectangles. */ int ! gs_rectclip(gs_state *pgs, const gs_rect *pr, uint count) { int code; if ( (code = gs_newpath(pgs)) < 0 || *************** *** 76,80 **** /* (We could do this a lot more efficiently.) */ int ! gs_rectfill(gs_state *pgs, gs_rect *pr, uint count) { int code; if ( (code = gs_gsave(pgs)) < 0 ) return code; --- 76,80 ---- /* (We could do this a lot more efficiently.) */ int ! gs_rectfill(gs_state *pgs, const gs_rect *pr, uint count) { int code; if ( (code = gs_gsave(pgs)) < 0 ) return code; *************** *** 91,95 **** /* (We could do this a lot more efficiently.) */ int ! gs_rectstroke(gs_state *pgs, gs_rect *pr, uint count, gs_matrix *pmat) { int code; if ( (code = gs_gsave(pgs)) < 0 ) return code; --- 91,96 ---- /* (We could do this a lot more efficiently.) */ int ! gs_rectstroke(gs_state *pgs, const gs_rect *pr, uint count, ! const gs_matrix *pmat) { int code; if ( (code = gs_gsave(pgs)) < 0 ) return code; diff -rc2N gs241/gsecho.bat gs25/gsecho.bat *** gs241/gsecho.bat Tue Jul 9 16:38:40 1991 --- gs25/gsecho.bat *************** *** 1,8 **** - @echo off - if '%1'=='-a' goto add - if exist %1 erase %1 - goto put - :add - shift - :put - echo %2 %3 %4 %5 %6 %7 %8 %9 >>%1 --- 0 ---- diff -rc2N gs241/gserrors.h gs25/gserrors.h *** gs241/gserrors.h Sun Mar 18 03:26:44 1990 --- gs25/gserrors.h Sat Aug 15 05:29:04 1992 *************** *** 26,29 **** --- 26,31 ---- /* We use ints rather than an enum to avoid a lot of casting. */ + #define gs_error_invalidaccess (-7) + #define gs_error_invalidfileaccess (-9) #define gs_error_invalidfont (-10) #define gs_error_ioerror (-12) *************** *** 31,35 **** --- 33,40 ---- #define gs_error_nocurrentpoint (-14) #define gs_error_rangecheck (-15) + #define gs_error_typecheck (-20) #define gs_error_undefined (-21) #define gs_error_undefinedresult (-23) #define gs_error_VMerror (-25) + + #define gs_error_Fatal (-100) diff -rc2N gs241/gsfont.c gs25/gsfont.c *** gs241/gsfont.c Mon Nov 25 22:20:44 1991 --- gs25/gsfont.c Wed Jul 29 13:44:54 1992 *************** *** 1,3 **** ! /* Copyright (C) 1989, 1990, 1991 Aladdin Enterprises. All rights reserved. Distributed by Free Software Foundation, Inc. --- 1,3 ---- ! /* Copyright (C) 1989, 1992 Aladdin Enterprises. All rights reserved. Distributed by Free Software Foundation, Inc. *************** *** 32,36 **** /* Imported procedures */ ! void gs_purge_font_from_char_caches(P2(gs_font_dir *, gs_font *)); /* Size of cache structures */ --- 32,36 ---- /* Imported procedures */ ! void gs_purge_font_from_char_caches(P2(gs_font_dir *, const gs_font *)); /* Size of cache structures */ *************** *** 118,122 **** /* scalefont */ int ! gs_scalefont(gs_font_dir *pdir, gs_font *pfont, floatp scale, gs_font **ppfont, gs_font **pdfont) { gs_matrix mat; --- 118,122 ---- /* scalefont */ int ! gs_scalefont(gs_font_dir *pdir, const gs_font *pfont, floatp scale, gs_font **ppfont, gs_font **pdfont) { gs_matrix mat; *************** *** 127,131 **** /* makefont */ int ! gs_makefont(gs_font_dir *pdir, gs_font *pfont, gs_matrix *pmat, gs_font **ppfont, gs_font **pdfont) { int code; --- 127,131 ---- /* makefont */ int ! gs_makefont(gs_font_dir *pdir, const gs_font *pfont, const gs_matrix *pmat, gs_font **ppfont, gs_font **pdfont) { int code; *************** *** 160,167 **** ) { *ppfont = pf_out; ! #ifdef DEBUG ! if ( gs_debug['m'] ) ! dprintf1("[m]found font=%lx\n", (ulong)pf_out); ! #endif return 0; } --- 160,164 ---- ) { *ppfont = pf_out; ! if_debug1('m', "[m]found font=%lx\n", (ulong)pf_out); return 0; } *************** *** 178,185 **** prev = prev->next ) ; ! #ifdef DEBUG ! if ( gs_debug['m'] ) ! dprintf1("[m]discarding font %lx\n", (ulong)prev); ! #endif *pdfont = prev; prev->prev->next = 0; --- 175,179 ---- prev = prev->next ) ; ! if_debug1('m', "[m]discarding font %lx\n", (ulong)prev); *pdfont = prev; prev->prev->next = 0; *************** *** 191,198 **** pf_out->dir = pdir; *ppfont = pf_out; ! #ifdef DEBUG ! if ( gs_debug['m'] ) ! dprintf1("[m]new font=%lx\n", (ulong)pf_out); ! #endif return 1; } --- 185,189 ---- pf_out->dir = pdir; *ppfont = pf_out; ! if_debug1('m', "[m]new font=%lx\n", (ulong)pf_out); return 1; } *************** *** 208,212 **** /* currentfont */ gs_font * ! gs_currentfont(gs_state *pgs) { return pgs->font; } --- 199,203 ---- /* currentfont */ gs_font * ! gs_currentfont(const gs_state *pgs) { return pgs->font; } *************** *** 214,218 **** /* cachestatus */ void ! gs_cachestatus(register gs_font_dir *pdir, register uint pstat[7]) { pstat[0] = pdir->bsize; pstat[1] = pdir->bmax; --- 205,209 ---- /* cachestatus */ void ! gs_cachestatus(register const gs_font_dir *pdir, register uint pstat[7]) { pstat[0] = pdir->bsize; pstat[1] = pdir->bmax; *************** *** 245,253 **** /* currentcacheparams */ uint ! gs_currentcachelower(gs_font_dir *pdir) { return pdir->lower; } uint ! gs_currentcacheupper(gs_font_dir *pdir) { return pdir->upper; } --- 236,244 ---- /* currentcacheparams */ uint ! gs_currentcachelower(const gs_font_dir *pdir) { return pdir->lower; } uint ! gs_currentcacheupper(const gs_font_dir *pdir) { return pdir->upper; } *************** *** 263,267 **** /* This is only used by restore (and, someday, the GC). */ void ! gs_purge_font_from_caches(gs_font_dir *pdir, gs_font *pfont) { /* Purge the font from the scaled font cache. */ --- 254,258 ---- /* This is only used by restore (and, someday, the GC). */ void ! gs_purge_font_from_caches(gs_font_dir *pdir, const gs_font *pfont) { /* Purge the font from the scaled font cache. */ *************** *** 276,280 **** } else if ( pf->base == pfont ) ! { gs_purge_font_from_caches(pdir, pf->base); pf = pdir->scaled_fonts; /* start over */ } --- 267,271 ---- } else if ( pf->base == pfont ) ! { gs_purge_font_from_caches(pdir, pf); pf = pdir->scaled_fonts; /* start over */ } diff -rc2N gs241/gsfont.h gs25/gsfont.h *** gs241/gsfont.h Mon Nov 25 22:08:00 1991 --- gs25/gsfont.h Fri May 1 12:15:20 1992 *************** *** 1,3 **** ! /* Copyright (C) 1989, 1991 Aladdin Enterprises. All rights reserved. Distributed by Free Software Foundation, Inc. --- 1,3 ---- ! /* Copyright (C) 1989, 1992 Aladdin Enterprises. All rights reserved. Distributed by Free Software Foundation, Inc. *************** *** 47,61 **** /* from the cache (or 0) in the latter case. This is for */ /* the benefit of reference-counted clients. */ ! int gs_scalefont(P5(gs_font_dir *, gs_font *, floatp, gs_font **, gs_font **)); ! int gs_makefont(P5(gs_font_dir *, gs_font *, gs_matrix *, gs_font **, gs_font **)); int gs_setfont(P2(gs_state *, gs_font *)); ! gs_font * gs_currentfont(P1(gs_state *)); ! void gs_purge_font_from_caches(P2(gs_font_dir *, gs_font *)); /* Font cache parameter operations */ ! void gs_cachestatus(P2(gs_font_dir *, uint [7])); int gs_setcachelimit(P2(gs_font_dir *, uint)); ! uint gs_currentcachelower(P1(gs_font_dir *)); int gs_setcachelower(P2(gs_font_dir *, uint)); ! uint gs_currentcacheupper(P1(gs_font_dir *)); int gs_setcacheupper(P2(gs_font_dir *, uint)); --- 47,61 ---- /* from the cache (or 0) in the latter case. This is for */ /* the benefit of reference-counted clients. */ ! int gs_scalefont(P5(gs_font_dir *, const gs_font *, floatp, gs_font **, gs_font **)); ! int gs_makefont(P5(gs_font_dir *, const gs_font *, const gs_matrix *, gs_font **, gs_font **)); int gs_setfont(P2(gs_state *, gs_font *)); ! gs_font * gs_currentfont(P1(const gs_state *)); ! void gs_purge_font_from_caches(P2(gs_font_dir *, const gs_font *)); /* Font cache parameter operations */ ! void gs_cachestatus(P2(const gs_font_dir *, uint [7])); int gs_setcachelimit(P2(gs_font_dir *, uint)); ! uint gs_currentcachelower(P1(const gs_font_dir *)); int gs_setcachelower(P2(gs_font_dir *, uint)); ! uint gs_currentcacheupper(P1(const gs_font_dir *)); int gs_setcacheupper(P2(gs_font_dir *, uint)); diff -rc2N gs241/gsgraph.icx gs25/gsgraph.icx *** gs241/gsgraph.icx --- gs25/gsgraph.icx Fri Jun 12 18:42:28 1992 *************** *** 0 **** --- 1,48 ---- + 0000010001002020100000000000e802 + 00001600000028000000200000004000 + 00000100040000000000800200000000 + 00000000000000000000000000000000 + 00000000800000800000008080008000 + 00008000800080800000808080004040 + 40000000ff0000ff000000ffff00ff00 + 0000ff00ff00ffff0000ffffff00cccc + cccccccccccccccccccccccccccccccc + ccccccccccccccbbbbccccccccccccbc + bccbccbccbbbbcccccbccbbbccccccbc + bccbccbcbcccbccbbbbcbcccccccccbc + bccbccbccbbbbcbcccbcbbbbbcccccbc + bccbccbcccccbcbcccbcbcccbcccccbc + bbbcbbcccbbbcccbbbbccbbbcccccccc + ccccccccccccccccccccccccccccccbc + cccccccccccccccccccccccccccccccc + cccccccccccccccccccccccccccc0000 + 00fffffffffffffffff0000000000000 + 000ffffffffffff0f000000000000000 + 0000ffffffffffff0000000000000000 + 00000ffffffffffff000000f000000ff + 000ff0fffffffffff00ffffff000000f + ffff0fffffffffff0ffffffff0000fff + fffff0fffffffffffffffffffff00000 + fffffffffffffffffffff000ff0000ff + f000fffffffffffffffff0000ff000f0 + 0000ffffffffffffffff000000000000 + 00000ffffffffffff0f0000000000000 + 0000000fff0ff00fff00000000000000 + 0000000ff0fff00fff00000000000000 + 0000000000ffffffff00000000000000 + 0000000000ffffffff00000000000000 + 0000000000ff0f0ff000000000000000 + 00000000000fffff0000000000000000 + 00000000000ffff00000000000000000 + 0000000000ffff000000000000000000 + 000000000ffff0000000000000000000 + 0000000000ff00000000000000000000 + 00000000000000000000000000000000 + 00000000000000000000000000000000 + 00000000000000000000000000000000 + 000000000000f80000fffc0001fffe00 + 07efcc00020780000003800000010000 + 0000800000018000003086000079df00 + 00ffff8001ffffc001ffffe001fffff8 + 01fffff803fffff807fffffc0ffffff8 + 1ffffff03ffffff87ffffffcffff diff -rc2N gs241/gsim2out.c gs25/gsim2out.c *** gs241/gsim2out.c Sun Mar 15 12:40:54 1992 --- gs25/gsim2out.c *************** *** 1,400 **** - /* Copyright (C) 1989, 1992 Aladdin Enterprises. All rights reserved. - Distributed by Free Software Foundation, Inc. - - This file is part of Ghostscript. - - Ghostscript is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY. No author or distributor accepts responsibility - to anyone for the consequences of using it or for whether it serves any - particular purpose or works at all, unless he says so in writing. Refer - to the Ghostscript General Public License for full details. - - Everyone is granted permission to copy, modify and redistribute - Ghostscript, but only under the conditions described in the Ghostscript - General Public License. A copy of this license is supposed to have been - given to you along with Ghostscript so you can know your rights and - responsibilities. It should be in a file named COPYING. Among other - things, the copyright notice and this notice must be preserved on all - copies. */ - - /* gsim2out.c */ - /* Image to outline conversion for GhostScript library */ - #include "gx.h" - #include "memory_.h" - #include "gserrors.h" - #include "gsmatrix.h" - #include "gsstate.h" - #include "gscoord.h" - #include "gxfixed.h" - #include "gxtype1.h" - - /* - * Convert a bitmap image to an outline (path) representation. - * The outline representation is in Adobe Type 1 CharString format. - * See ghost.doc for more details. - */ - - /* Define the state of the conversion process. */ - typedef struct { - /* The following are set at the beginning of the conversion. */ - gs_matrix ifm; /* inverse of (CTM */ - /* scaled by width/height * 4). */ - byte *limit; /* stop output here */ - int ox, oy; /* X/Y pixel offset of char origin */ - /* The following are updated dynamically. */ - byte *next; /* next byte goes here */ - int px, py; /* X/Y position at start of run */ - int cpx, cpy; /* px/py in character coordinates */ - int dx, dy; /* X/Y increment of current run */ - int count; /* # of steps in current run */ - } status; - - /* Define the scaling for the path tracer. */ - #define outline_scale 4 - - /* Forward declarations */ - private int round_coord(P1(floatp)); - private int put_int(P2(status *, int)); - private void fill_cells(P4(byte *, byte *, int, int)); - private int trace_cells(P4(byte *, int, int, status *)); - - /* - * gs_type1imagepath encodes an image into a byte string supplied - * by the caller. If the string is not big enough, the procedure - * returns gs_error_limitcheck. Otherwise, the procedure returns - * the actual number of bytes of data stored. - */ - int - gs_type1imagepath(gs_state *pgs, byte *data, int width, int height, - floatp wx, floatp wy, floatp origin_x, floatp origin_y, - byte *str, uint maxlen) - { uint csize; - byte *cells; - status stat; - status *out = &stat; - int lsbx; - int iwx, iwy, ilsbx, ilsby; - int code; - /* Construct the coordinate transformation. */ - { float hsc = height * outline_scale; - gs_matrix mat; - gs_currentmatrix(pgs, &stat.ifm); - #ifdef DEBUG - if ( gs_debug['0'] ) - dprintf6("[0]ctm=[%g %g %g %g %g %g]\n", - stat.ifm.xx, stat.ifm.xy, stat.ifm.yx, stat.ifm.yy, - stat.ifm.tx, stat.ifm.ty); - #endif - if ( (code = gs_make_scaling(hsc, hsc, &mat)) < 0 || - (code = gs_matrix_multiply(&mat, &stat.ifm, &stat.ifm)) < 0 || - (code = gs_matrix_invert(&stat.ifm, &stat.ifm)) < 0 - ) - return code; - } - /* Allocate and fill in the cell matrix. */ - csize = (width + 2) * (height + 2); - cells = (byte *)gs_malloc(csize, 1, "gsim2out cells"); - if ( cells == 0 ) return_error(gs_error_VMerror); - fill_cells(cells, data, width, height); - /* Initialize the rest of the state. */ - stat.next = str; - stat.limit = str + maxlen; - /* Determine the left side bearing by looking for */ - /* the leftmost column with any 1-bits. */ - for ( lsbx = 0; lsbx < width; lsbx++ ) - { int y; - for ( y = 1; y <= height; y++ ) - if ( cells[y * (width + 2) + lsbx + 1] ) goto xit; - } - xit: /* Encode the origin, width, and side bearing. */ - { gs_point opt, wpt, lsbpt; - if ( (code = gs_distance_transform(origin_x * outline_scale, - origin_y * outline_scale, - &stat.ifm, &opt)) < 0 || - (code = gs_distance_transform(wx * outline_scale, - wy * outline_scale, - &stat.ifm, &wpt)) < 0 || - (code = gs_distance_transform((lsbx - origin_x) * - outline_scale, (floatp)0, - &stat.ifm, &lsbpt)) < 0 - ) - return code; - stat.ox = round_coord(opt.x); - stat.oy = round_coord(opt.y); - iwx = round_coord(wpt.x); - iwy = round_coord(wpt.y); - ilsbx = round_coord(lsbpt.x); - ilsby = round_coord(lsbpt.y); - #ifdef DEBUG - if ( gs_debug['0'] ) - { int cy, cx; - byte *cp = data; - dprintf6("[0]w=%d h=%d oxy=(%g,%g) wxy=(%g,%g)\n", - width, height, origin_x, origin_y, wx, wy); - dprintf6(" io=(%d,%d) iw=(%d,%d) ilsb=(%d,%d)\n", - stat.ox, stat.oy, iwx, iwy, ilsbx, ilsby); - for ( cy = 0; cy < height; cy++ ) - { dprintf1("[0]%3d ", cy); - for ( cx = 0; cx < width; cx += 8 ) - dprintf1("%02x", (int)*cp++); - dputc('\n'); - } - } - #endif - if ( (code = put_int(out, ilsbx)) < 0 ) return code; - if ( iwy != 0 || ilsby != 0 ) - { if ( (code = put_int(out, ilsby)) < 0 || - (code = put_int(out, iwx)) < 0 || - (code = put_int(out, iwy)) < 0 - ) - return code; - if ( stat.next + 2 > stat.limit ) - return_error(gs_error_limitcheck); - *stat.next++ = (byte)c_escape; - *stat.next++ = (byte)ce_sbw; - } - else - { if ( (code = put_int(out, iwx)) < 0 ) return code; - if ( stat.next + 1 > stat.limit ) - return_error(gs_error_limitcheck); - *stat.next++ = (byte)c_hsbw; - } - } - /* Since all further movements are relative, we can account */ - /* for the origin by simply setting px/py to the lsb, */ - /* and cpx/cpy to the lsb plus the origin. */ - stat.px = (lsbx * outline_scale); - stat.py = (int)(origin_y * outline_scale); - stat.cpx = ilsbx + stat.ox; - stat.cpy = ilsby + stat.oy; - /* Trace the outline of the cells. */ - code = trace_cells(cells, width, height, out); - gs_free((char *)cells, csize, 1, "gsim2out cells"); - if ( code < 0 ) return code; - if ( stat.next >= stat.limit ) return_error(gs_error_limitcheck); - *stat.next++ = (byte)c_endchar; - return stat.next - str; - } - - /* Fill the cell matrix with the image being traced. */ - /* The cell matrix has a row and column of zero padding on each side, */ - /* so we don't have to check for boundary conditions all the time. */ - /* Note that the image data are in PostScript / Ghostscript standard */ - /* order (left to right, top row first), but the cells are stored */ - /* bottom row first. */ - private void - fill_cells(byte *cells, byte *data, int width, int height) - { int y; - byte *dptr = data - 1; - byte *cptr = cells + (width + 2) * height + 1; - memset(cells, 0, (width + 2) * (height + 2)); - for ( y = 0; y < height; y++ ) - { register int mask = 0; - register int b; - register int x; - for ( x = 0; x < width; x++, mask >>= 1, cptr++ ) - { if ( mask == 0 ) mask = 0x80, b = *++dptr; - if ( b & mask ) *cptr = 1; - } - cptr -= width * 2 + 2; /* back up 1 row */ - } - } - - /* Trace the cells to form an outline. The trace goes in clockwise */ - /* order, always starting by going west along a bottom edge. */ - /* All the subsidiary routines return 0 on success, */ - /* -1 if the output buffer overflowed. */ - private int trace_from(P3(status *, byte *, int)); - private int add_dxdy(P4(status *, int, int, int)); - #define add_deltas(s, dx, dy, n)\ - if ( (code = add_dxdy(s, dx, dy, n)) < 0 ) return code - private int put_dxdy(P4(status *, int, int, int)); - #define put_deltas(s, dx, dy, moving)\ - if ( (code = put_dxdy(s, dx, dy, moving)) < 0 ) return code - private int - trace_cells(byte *cells, int width, int height, register status *out) - { byte *cptr; - int code; - for ( cptr = cells + (width + 2) * (height + 1) - 2; - cptr >= cells; cptr-- - ) - { if ( *cptr == 1 && cptr[-(width+2)] == 0 ) - { /* Found a starting point */ - int x = (cptr-cells) % (width+2) - 1; - int y = (cptr-cells) / (width+2) - 1; - put_deltas(out, - x * outline_scale + 1 - out->px, - y * outline_scale - out->py, - 1); - out->count = 0; - if ( (code = trace_from(out, cptr, width)) < 0 ) - return code; - if ( out->next >= out->limit ) - return_error(gs_error_limitcheck); - *out->next++ = (byte)c_closepath; - } - } - return 0; - } - - /* Trace a path */ - private int - trace_from(register status *out, byte *cptr, int width) - { typedef enum { /* must be in this order */ - north = 0, east = 1, south = 2, west = 3 - } direction; - direction dir; - int w2 = width + 2; /* actual width of cell rows */ - int part; /* how far along edge we are */ - int code; - /* Movement tables */ - typedef struct { - short tx, ty; /* relative index of first cell */ - /* to test (counter-clockwise move) */ - short dx, dy; /* continue in same direction */ - } dir_descr; - static dir_descr nesw[4+1] = - { /* Going north (along a western edge) */ - { -1, 1, 0, 1 }, - /* Going east (along a northern edge) */ - { 1, 1, 1, 0 }, - /* Going south (along an eastern edge) */ - { 1, -1, 0, -1 }, - /* Going west (along a southern edge) */ - { -1, -1, -1, 0 }, - /* An extra copy of north */ - { -1, 1, 0, 1 } - }; - for ( dir = west, part = 1; ; ) - { register dir_descr *pd = &nesw[(int)dir]; - int dx = pd->dx, dy = pd->dy; - int delta; - if ( dir == west ) - { /* This is the only case that has to check */ - /* for the end of a subpath. */ - if ( *cptr == 2 ) return 0; - *cptr = 2; - } - delta = pd->ty * w2 + pd->tx; - if ( cptr[delta] ) /* go counter-clockwise */ - { cptr += delta; - add_deltas(out, dx, dy, 1 - part); - add_deltas(out, pd->tx, pd->ty, outline_scale - 1); - dir = (direction)(((int)dir - 1) & 3); - part = outline_scale - 1; - continue; - } - delta = dy * w2 + dx; - if ( !cptr[delta] ) /* go clockwise */ - { add_deltas(out, dx, dy, outline_scale - 1 - part); - add_deltas(out, dx + pd[1].dx, dy + pd[1].dy, 1); - dir = (direction)(((int)dir + 1) & 3); - part = 1; - continue; - } - cptr += delta; /* go in same direction */ - add_deltas(out, dx, dy, outline_scale); - } - } - - /* Add a (dx, dy) pair to the path being formed. */ - /* Accumulate successive segments in the same direction. */ - private int - add_dxdy(register status *out, int dx, int dy, int count) - { int code; - if ( count != 0 ) - { if ( dx == out->dx && dy == out->dy ) - out->count += count; - else - { if ( out->count != 0 ) - put_deltas(out, out->dx * out->count, - out->dy * out->count, 0); - out->dx = dx, out->dy = dy; - out->count = count; - } - } - return 0; - } - - /* Encode a (dx, dy) pair onto the path. */ - /* If there isn't enough space, return -1. */ - private int - put_dxdy(register status *out, int dx, int dy, int moving) - { int code; - /* We do the arithmetic in the 1/4-pixel coordinate system, */ - /* and then transform the result, to avoid accumulating */ - /* rounding errors. */ - int npx = out->px + dx, npy = out->py + dy; - gs_point npt; - int ncpx, ncpy; - int cdx, cdy; - gs_distance_transform((floatp)npx, (floatp)npy, &out->ifm, &npt); - ncpx = round_coord(npt.x); - ncpy = round_coord(npt.y); - cdx = ncpx - out->cpx; - cdy = ncpy - out->cpy; - #ifdef DEBUG - if ( gs_debug['0'] ) - dprintf8("[0] pxy=(%d,%d)+(%d,%d) cpxy=(%d,%d)+(%d,%d)\n", - out->px, out->py, dx, dy, out->cpx, out->cpy, cdx, cdy); - #endif - if ( cdx != 0 || cdy == 0 ) /* encode dx if needed */ - if ( (code = put_int(out, cdx)) < 0 ) return code; - if ( cdy != 0 ) /* encode dy if needed */ - if ( (code = put_int(out, cdy)) < 0 ) return code; - if ( out->next == out->limit ) return_error(gs_error_limitcheck); - *out->next++ = (byte) - (cdy == 0 ? /* use hmove/lineto */ - (moving ? c_hmoveto : c_hlineto) : - cdx == 0 ? /* use vmove/lineto */ - (moving ? c_vmoveto : c_vlineto) : - (moving ? c_rmoveto : c_rlineto)); - out->px = npx, out->py = npy; - out->cpx = ncpx, out->cpy = ncpy; - return 0; - } - - /* Round a floating point coordinate. If it is out of range, */ - /* return a limiting value. */ - private int - round_coord(floatp v) - { long c = (long)(v + 0.5); - return( c > 0x7fff ? 0x7fff : - c < -0x7fff ? -0x7fff : - (int)c ); - } - /* Encode a single number in Type 1 representation. */ - private int - put_int(status *out, register int v) - { - #define min_enc_num1 ((c_num1 - c_num2 + 1) / 2) - #define max_enc_num1 ((c_num2 - c_num1 - 1) / 2) - #define min_enc_num2 (max_enc_num1 + 1) - #define max_enc_num2 (min_enc_num2 + (c_num3 - c_num2) * 256 - 1) - #define min_enc_num3 (-max_enc_num2) - #define max_enc_num3 (-min_enc_num2) - register byte *ptr = out->next; - if ( ptr + 5 > out->limit ) /* conservative test is faster */ - return_error(gs_error_limitcheck); - if ( v >= min_enc_num1 && v <= max_enc_num1 ) - *ptr++ = v - min_enc_num1 + c_num1; - else if ( v >= min_enc_num2 && v <= max_enc_num2 ) - { v -= min_enc_num2; - *ptr++ = (v >> 8) + c_num2; - *ptr++ = v & 0xff; - } - else if ( v >= min_enc_num3 && v <= max_enc_num3 ) - { v = -(v - max_enc_num3); - *ptr++ = (v >> 8) + c_num3; - *ptr++ = v & 0xff; - } - else - { *ptr++ = c_num4; - *ptr++ = ((long)v >> 24) & 0xff; - *ptr++ = ((long)v >> 16) & 0xff; - *ptr++ = (v >> 8) & 0xff; - *ptr++ = v & 0xff; - } - out->next = ptr; - return 0; - } --- 0 ---- diff -rc2N gs241/gsimage.c gs25/gsimage.c *** gs241/gsimage.c Sat Apr 18 14:39:58 1992 --- gs25/gsimage.c Sat Aug 8 10:12:36 1992 *************** *** 22,25 **** --- 22,26 ---- #include "gx.h" #include "memory_.h" + #include "gpcheck.h" #include "gserrors.h" #include "gxfixed.h" *************** *** 39,53 **** /* Forward declarations */ private int image_init(P9(gs_image_enum *, int, int, int, int, int, gs_matrix *, gs_state *, fixed)); /* Procedures for unpacking the input data into 8 bits/sample. */ private void image_unpack_1(iunpack_proc_args); ! private void image_unpack_1_spread(iunpack_proc_args); private void image_unpack_2(iunpack_proc_args); ! private void image_unpack_2_spread(iunpack_proc_args); private void image_unpack_4(iunpack_proc_args); private void image_unpack_8(iunpack_proc_args); ! private void image_unpack_8_spread(iunpack_proc_args); ! private void image_unpack_12(iunpack_proc_args); /* The image_render procedures work on fully expanded, complete rows. */ /* These take a height argument, which is an integer > 0; */ --- 40,56 ---- /* Forward declarations */ + private int image_init_map(P3(byte *, int, const float *)); private int image_init(P9(gs_image_enum *, int, int, int, int, int, gs_matrix *, gs_state *, fixed)); /* Procedures for unpacking the input data into 8 bits/sample. */ + /* Some of these have been split off to gsimage2. */ private void image_unpack_1(iunpack_proc_args); ! extern void image_unpack_1_spread(iunpack_proc_args); private void image_unpack_2(iunpack_proc_args); ! extern void image_unpack_2_spread(iunpack_proc_args); private void image_unpack_4(iunpack_proc_args); private void image_unpack_8(iunpack_proc_args); ! extern void image_unpack_8_spread(iunpack_proc_args); ! extern void image_unpack_12(iunpack_proc_args); /* The image_render procedures work on fully expanded, complete rows. */ /* These take a height argument, which is an integer > 0; */ *************** *** 56,68 **** private int image_render_skip(irender_proc_args); private int image_render_direct(irender_proc_args); private int image_render_mono(irender_proc_args); ! private int image_render_color(irender_proc_args); /* Set up a gs_color with a transfer-mapped gray sample. */ #define image_set_rgb(rcolor,sample_value)\ ! rcolor.luminance = rcolor.red = rcolor.green = rcolor.blue =\ ! gx_map_color_param_byte(pgs, sample_value, gray) ! /* Mask tables for spreading input data. */ /* Note that the mask tables depend on the end-orientation of the CPU. */ /* We can't simply define them as byte arrays, because */ --- 59,73 ---- private int image_render_skip(irender_proc_args); private int image_render_direct(irender_proc_args); + private int image_render_simple(irender_proc_args); private int image_render_mono(irender_proc_args); ! extern int image_render_color(irender_proc_args); /* Set up a gs_color with a transfer-mapped gray sample. */ #define image_set_rgb(rcolor,sample_value)\ ! (rcolor.luminance = rcolor.red = rcolor.green = rcolor.blue =\ ! gx_map_color_param_byte(pgs, sample_value, gray),\ ! gx_color_from_rgb(&rcolor)) ! /* Standard mask tables for spreading input data. */ /* Note that the mask tables depend on the end-orientation of the CPU. */ /* We can't simply define them as byte arrays, because */ *************** *** 74,90 **** z^(c+d), z^(a+c+d), z^(b+c+d), z^(a+b+c+d) #if arch_is_big_endian ! private unsigned long map_4_to_32[16] = { map4tox(0L, 0xffL, 0xff00L, 0xff0000L, 0xff000000L) }; ! private unsigned long map_4_to_32_invert[16] = { map4tox(0xffffffffL, 0xffL, 0xff00L, 0xff0000L, 0xff000000L) }; - private unsigned short map_4_to_16[16] = - { map4tox(0, 0x55, 0xaa, 0x5500, 0xaa00) }; #else /* !arch_is_big_endian */ ! private unsigned long map_4_to_32[16] = { map4tox(0L, 0xff000000L, 0xff0000L, 0xff00L, 0xffL) }; ! private unsigned long map_4_to_32_invert[16] = { map4tox(0xffffffffL, 0xff000000L, 0xff0000L, 0xff00L, 0xffL) }; - private unsigned short map_4_to_16[16] = - { map4tox(0, 0x5500, 0xaa00, 0x55, 0xaa) }; #endif --- 79,91 ---- z^(c+d), z^(a+c+d), z^(b+c+d), z^(a+b+c+d) #if arch_is_big_endian ! private const unsigned long map_4x1_to_32[16] = { map4tox(0L, 0xffL, 0xff00L, 0xff0000L, 0xff000000L) }; ! private const unsigned long map_4x1_to_32_invert[16] = { map4tox(0xffffffffL, 0xffL, 0xff00L, 0xff0000L, 0xff000000L) }; #else /* !arch_is_big_endian */ ! private const unsigned long map_4x1_to_32[16] = { map4tox(0L, 0xff000000L, 0xff0000L, 0xff00L, 0xffL) }; ! private const unsigned long map_4x1_to_32_invert[16] = { map4tox(0xffffffffL, 0xff000000L, 0xff0000L, 0xff00L, 0xffL) }; #endif *************** *** 92,98 **** int gs_image_init(gs_image_enum *penum, gs_state *pgs, ! int width, int height, int bps, int spp, gs_matrix *pmat) { int spread; ! if ( pgs->in_cachedevice ) return_error(gs_error_undefined); switch ( spp ) { --- 93,103 ---- int gs_image_init(gs_image_enum *penum, gs_state *pgs, ! int width, int height, int bps, int spp, const float *decode, ! gs_matrix *pmat) { int spread; ! int code; ! static const float decode_01[2] = { 0.0, 1.0 }; ! if ( pgs->in_cachedevice ) ! return_error(gs_error_undefined); switch ( spp ) { *************** *** 146,153 **** } penum->masked = 0; ! penum->map4to32 = map_4_to_32; return image_init(penum, width, height, bps, spp, spread, pmat, pgs, (fixed)0); } /* Start processing a masked image */ --- 151,209 ---- } penum->masked = 0; ! /* Initialize the map from samples to intensities. */ ! if ( decode == 0 ) ! decode = decode_01; ! if ( bps > 2 || spread != 1 ) ! code = image_init_map(&penum->map.to8[0], 1 << bps, decode); ! else ! { /* The map index encompasses more than one pixel. */ ! byte map[4]; ! register int i; ! code = image_init_map(&map[0], 1 << bps, decode); ! switch ( bps ) ! { ! case 1: ! { register ulong *p = &penum->map.from4x1to32[0]; ! if ( map[0] == 0 && map[1] == 0xff ) ! memcpy((byte *)p, map_4x1_to_32, 16 * 4); ! else if ( map[0] == 0xff && map[1] == 0 ) ! memcpy((byte *)p, map_4x1_to_32_invert, 16 * 4); ! else ! for ( i = 0; i < 16; i++, p++ ) ! ((byte *)p)[0] = map[i >> 3], ! ((byte *)p)[1] = map[(i >> 2) & 1], ! ((byte *)p)[2] = map[(i >> 1) & 1], ! ((byte *)p)[3] = map[i & 1]; ! } break; ! case 2: ! { register ushort *p = &penum->map.from2x2to16[0]; ! for ( i = 0; i < 16; i++, p++ ) ! ((byte *)p)[0] = map[i >> 2], ! ((byte *)p)[1] = map[i & 3]; ! } break; ! } ! } ! if ( code < 0 ) return code; return image_init(penum, width, height, bps, spp, spread, pmat, pgs, (fixed)0); } + /* Construct a mapping table for sample values. */ + /* map_size is 2, 4, 16, or 256. Note that 255 % (map_size - 1) == 0. */ + private int + image_init_map(byte *map, int map_size, const float *decode) + { float min_v = decode[0], max_v = decode[1]; + uint value; + uint diff; + byte *limit = map + map_size; + if ( min_v < 0 || min_v > 1 || max_v < 0 || max_v > 1 ) + return_error(gs_error_rangecheck); + value = min_v * 0xffffL; + /* The division in the next statement is exact, */ + /* see the comment above. */ + diff = (max_v - min_v) * (0xffffL / (map_size - 1)); + for ( ; map != limit; map++, value += diff ) + *map = value >> 8; + return 0; + } /* Start processing a masked image */ *************** *** 160,164 **** penum->icolor1 = *pgs->dev_color; penum->masked = 1; ! penum->map4to32 = (invert ? map_4_to_32_invert : map_4_to_32); return image_init(penum, width, height, 1, 1, 1, pmat, pgs, (adjust && pgs->in_cachedevice ? --- 216,222 ---- penum->icolor1 = *pgs->dev_color; penum->masked = 1; ! memcpy(&penum->map.from4x1to32[0], ! (invert ? map_4x1_to_32_invert : map_4x1_to_32), ! 16 * 4); return image_init(penum, width, height, 1, 1, 1, pmat, pgs, (adjust && pgs->in_cachedevice ? *************** *** 167,171 **** /* Common setup for image and imagemask. */ ! /* Caller has set penum->masked, map4to32, dev_colors[]. */ private int image_init(register gs_image_enum *penum, int width, int height, --- 225,229 ---- /* Common setup for image and imagemask. */ ! /* Caller has set penum->masked, map, dev_colors[]. */ private int image_init(register gs_image_enum *penum, int width, int height, *************** *** 202,214 **** penum->spread = spread; penum->fxx = float2fixed(mat.xx); penum->fyy = float2fixed(mat.yy); ! if ( (penum->skewed = is_skewed(&mat)) ) ! { penum->fxy = float2fixed(mat.xy); ! penum->fyx = float2fixed(mat.yx); ! } ! else ! { penum->fxy = 0; ! penum->fyx = 0; ! } penum->xcur = mtx = float2fixed(mat.tx); penum->ycur = mty = float2fixed(mat.ty); --- 260,267 ---- penum->spread = spread; penum->fxx = float2fixed(mat.xx); + penum->fxy = float2fixed(mat.xy); + penum->fyx = float2fixed(mat.yx); penum->fyy = float2fixed(mat.yy); ! penum->skewed = (penum->fxy | penum->fyx) != 0; penum->xcur = mtx = float2fixed(mat.tx); penum->ycur = mty = float2fixed(mat.ty); *************** *** 241,252 **** mtx + epx >= cbox.p.x && mtx + eqx <= cbox.q.x && mty + epy >= cbox.p.y && mty + eqy <= cbox.q.y; ! #ifdef DEBUG ! if ( gs_debug['b'] | gs_debug['B'] ) ! dprintf4("[b]Image: cbox=(%g,%g),(%g,%g)\n", ! fixed2float(cbox.p.x), fixed2float(cbox.p.y), ! fixed2float(cbox.q.x), fixed2float(cbox.q.y)), ! dprintf3(" mt=(%g,%g) never_clip=%d\n", ! fixed2float(mtx), fixed2float(mty), penum->never_clip); ! #endif } { static void (*procs[5])(iunpack_proc_args) = { --- 294,303 ---- mtx + epx >= cbox.p.x && mtx + eqx <= cbox.q.x && mty + epy >= cbox.p.y && mty + eqy <= cbox.q.y; ! if_debug7('b', ! "[b]Image: cbox=(%g,%g),(%g,%g)\n mt=(%g,%g) never_clip=%d\n", ! fixed2float(cbox.p.x), fixed2float(cbox.p.y), ! fixed2float(cbox.q.x), fixed2float(cbox.q.y), ! fixed2float(mtx), fixed2float(mty), ! penum->never_clip); } { static void (*procs[5])(iunpack_proc_args) = { *************** *** 266,274 **** penum->render = image_render_skip; else if ( spp == 1 && bps == 1 && !penum->slow_loop && ! (fixed2long_rounded(mtx + width * penum->fxx) - ! fixed2long_rounded(mtx) == width) && ! (penum->masked || color_is_pure(&penum->icolor0)) ) ! penum->render = image_render_direct; else penum->render = --- 317,330 ---- penum->render = image_render_skip; else if ( spp == 1 && bps == 1 && !penum->slow_loop && ! (penum->masked || ! (color_is_pure(&penum->icolor0) && ! color_is_pure(&penum->icolor1))) ) ! penum->render = ! (fixed2long_rounded(mtx + width * penum->fxx) - ! fixed2long_rounded(mtx) == width ? ! image_render_direct : ! penum->masked ? image_render_mono : ! image_render_simple); else penum->render = *************** *** 277,281 **** /* a conditional expression, but the Ultrix C compiler */ /* can't handle it. */ ! if ( penum->render == image_render_direct ) { penum->unpack = image_unpack_8; /* If the image is 1-for-1 with the device, */ --- 333,339 ---- /* a conditional expression, but the Ultrix C compiler */ /* can't handle it. */ ! if ( penum->render == image_render_direct || ! penum->render == image_render_simple ! ) { penum->unpack = image_unpack_8; /* If the image is 1-for-1 with the device, */ *************** *** 303,313 **** penum->byte_in_row = 0; penum->y = 0; ! #ifdef DEBUG ! if ( gs_debug['b'] | gs_debug['B'] ) ! dprintf3("[b]Image: w=%d h=%d %s\n", ! width, height, (penum->never_clip ? "no clip" : "must clip")), ! dprintf6(" [%f %f %f %f %f %f]\n", mat.xx, mat.xy, mat.yx, mat.yy, mat.tx, mat.ty); - #endif return 0; } --- 361,368 ---- penum->byte_in_row = 0; penum->y = 0; ! if_debug9('b', "[b]Image: w=%d h=%d %s\n [%f %f %f %f %f %f]\n", ! width, height, ! (penum->never_clip ? "no clip" : "must clip"), mat.xx, mat.xy, mat.yx, mat.yy, mat.tx, mat.ty); return 0; } *************** *** 406,436 **** private void ! image_unpack_1(gs_image_enum *penum, byte *bptr, ! register byte *data, uint dsize, uint inpos) ! { register unsigned long *bufp = (unsigned long *)bptr; int left = dsize; ! register unsigned long _ds *map = penum->map4to32; /* may invert */ ! while ( left-- ) ! { register unsigned b = *data++; ! *bufp++ = map[b >> 4]; ! *bufp++ = map[b & 0xf]; } ! } ! ! private void ! image_unpack_1_spread(gs_image_enum *penum, register byte *bufp, ! register byte *data, uint dsize, uint inpos) ! { register int spread = penum->spread; ! int left = dsize; while ( left-- ) ! { register unsigned b = *data++; ! *bufp = -(b >> 7); bufp += spread; ! *bufp = -((b >> 6) & 1); bufp += spread; ! *bufp = -((b >> 5) & 1); bufp += spread; ! *bufp = -((b >> 4) & 1); bufp += spread; ! *bufp = -((b >> 3) & 1); bufp += spread; ! *bufp = -((b >> 2) & 1); bufp += spread; ! *bufp = -((b >> 1) & 1); bufp += spread; ! *bufp = -(b & 1); bufp += spread; } } --- 461,485 ---- private void ! image_unpack_1(const gs_image_enum *penum, byte *bptr, ! register const byte *data, uint dsize, uint inpos) ! { register ulong *bufp = (unsigned long *)bptr; int left = dsize; ! register const ulong *map = &penum->map.from4x1to32[0]; ! register uint b; ! if ( left & 1 ) ! { b = data[0]; ! bufp[0] = map[b >> 4]; ! bufp[1] = map[b & 0xf]; ! data++, bufp += 2; } ! left >>= 1; while ( left-- ) ! { b = data[0]; ! bufp[0] = map[b >> 4]; ! bufp[1] = map[b & 0xf]; ! b = data[1]; ! bufp[2] = map[b >> 4]; ! bufp[3] = map[b & 0xf]; ! data += 2, bufp += 4; } } *************** *** 437,445 **** private void ! image_unpack_2(gs_image_enum *penum, byte *bptr, ! register byte *data, uint dsize, uint inpos) ! { register unsigned short *bufp = (unsigned short *)bptr; int left = dsize; ! register unsigned short _ds *map = map_4_to_16; while ( left-- ) { register unsigned b = *data++; --- 486,494 ---- private void ! image_unpack_2(const gs_image_enum *penum, byte *bptr, ! register const byte *data, uint dsize, uint inpos) ! { register ushort *bufp = (unsigned short *)bptr; int left = dsize; ! register const ushort *map = &penum->map.from2x2to16[0]; while ( left-- ) { register unsigned b = *data++; *************** *** 450,478 **** private void ! image_unpack_2_spread(gs_image_enum *penum, register byte *bufp, ! register byte *data, uint dsize, uint inpos) ! { register int spread = penum->spread; ! int left = dsize; ! static byte map_2_to_8[4] = { 0, 0x55, 0xaa, 0xff }; ! register byte _ds *map = map_2_to_8; ! while ( left-- ) ! { register unsigned b = *data++; ! *bufp = map[b >> 6]; bufp += spread; ! *bufp = map[(b >> 4) & 3]; bufp += spread; ! *bufp = map[(b >> 2) & 3]; bufp += spread; ! *bufp = map[b & 3]; bufp += spread; ! } ! } ! ! private void ! image_unpack_4(gs_image_enum *penum, register byte *bufp, ! register byte *data, uint dsize, uint inpos) { register int spread = penum->spread; int left = dsize; while ( left-- ) { register unsigned b = *data++; ! *bufp = (b & 0xf0) + (b >> 4); bufp += spread; ! b &= 0xf; ! *bufp = (b << 4) + b; bufp += spread; } } --- 499,511 ---- private void ! image_unpack_4(const gs_image_enum *penum, register byte *bufp, ! register const byte *data, uint dsize, uint inpos) { register int spread = penum->spread; int left = dsize; + register const byte *map = &penum->map.to8[0]; while ( left-- ) { register unsigned b = *data++; ! *bufp = map[b >> 4]; bufp += spread; ! *bufp = map[b & 0xf]; bufp += spread; } } *************** *** 479,542 **** private void ! image_unpack_8(gs_image_enum *penum, byte *bufp, ! byte *data, uint dsize, uint inpos) { if ( data != bufp ) memcpy(bufp, data, dsize); } - private void - image_unpack_8_spread(gs_image_enum *penum, register byte *bufp, - register byte *data, uint dsize, uint inpos) - { register int spread = penum->spread; - register int left = dsize; - while ( left-- ) - { *bufp = *data++; bufp += spread; - } - } - - private void - image_unpack_12(gs_image_enum *penum, register byte *bufp, - register byte *data, uint dsize, uint inpos) - { register int spread = penum->spread; - register int left = dsize; - /* We have to deal with the 3 cases of inpos % 3 separately. */ - /* (In fact, this is the only reason inpos is passed to */ - /* the unpacking procedures at all.) */ - /* Let N = inpos / 3. */ - switch ( inpos % 3 ) - { - case 1: - /* bufp points to byte 2N, which was already filled */ - /* with the leftover byte from the previous call. */ - bufp += spread; - *bufp = *data++ << 4; - if ( !--left ) return; - case 2: - /* bufp points to byte 2N+1, which was half-filled */ - /* with the second leftover byte from the previous call. */ - *bufp += *data++ >> 4; - --left; - case 0: - /* Nothing special to do. */ - ; - } - /* Just drop the low 4 bits of each 12. */ - while ( left >= 3 ) - { *bufp = *data; - bufp += spread; - *bufp = (data[1] << 4) + (data[2] >> 4); - bufp += spread; - data += 3; - } - switch ( left ) - { - case 2: /* dddddddd xxxxdddd */ - bufp[1] = data[1] << 4; - case 1: /* dddddddd */ - *bufp = *data; - case 0: /* Nothing more to do. */ - ; - } - } - /* ------ Rendering procedures ------ */ --- 512,520 ---- private void ! image_unpack_8(const gs_image_enum *penum, byte *bufp, ! const byte *data, uint dsize, uint inpos) { if ( data != bufp ) memcpy(bufp, data, dsize); } /* ------ Rendering procedures ------ */ *************** *** 561,579 **** zero = penum->icolor0.color1, one = penum->icolor1.color1; ! #ifdef DEBUG ! if ( gs_debug['b'] | gs_debug['B'] ) ! dprintf4("[b]direct (%d,%d),(%d,%d)\n", ix, iy, iw, ih); ! #endif /* Check for inverted imagemask */ ! if ( penum->map4to32 == map_4_to_32_invert ) zero = penum->icolor1.color1, one = penum->icolor0.color1; - if ( ih == 1 && h == 1 && penum->fyy >= 0 ) - { /* We can do the whole thing at once. */ - (*copy_mono)(dev, data, 0, raster, gx_no_bitmap_id, - ix, iy, iw, ih, zero, one); - return h; - } - else { /* Do just one row, clipping if necessary. */ int dy; --- 539,547 ---- zero = penum->icolor0.color1, one = penum->icolor1.color1; ! if_debug4('b', "[b]direct (%d,%d),(%d,%d)\n", ix, iy, iw, ih); /* Check for inverted imagemask */ ! if ( penum->map.from4x1to32[0] != 0 ) zero = penum->icolor1.color1, one = penum->icolor0.color1; { /* Do just one row, clipping if necessary. */ int dy; *************** *** 581,584 **** --- 549,553 ---- (*copy_mono)(dev, data, 0, raster, gx_no_bitmap_id, ix, iy + dy, iw, 1, zero, one); + gp_check_interrupts(); return 1; } *************** *** 585,588 **** --- 554,644 ---- } + /* Rendering procedure for a non-mask monobit image with no */ + /* skew or rotation and pure colors. */ + private int + image_render_simple(gs_image_enum *penum, byte *buffer, uint w, int h) + { fixed xrun = penum->xcur + fixed_half; + fixed xl; + const fixed dxx = penum->fxx; + const fixed dxx_8 = dxx << 3; + register const byte *psrc = buffer; + gx_device *dev = penum->pgs->device->info; + dev_proc_fill_rectangle((*fill_proc)) = dev->procs->fill_rectangle; + const int iy = penum->yci, ih = penum->hci; + gx_color_index + zero = penum->icolor0.color1, + one = penum->icolor1.color1; + int sbit = 7; + byte *endp = buffer + (w >> 3); + const int endbit = ~w & 7; + const byte endmask = 1 << endbit; + int xi = fixed2int_var(xrun); + int xni, code; + byte data; + if ( penum->map.from4x1to32[0] != 0 ) + zero = penum->icolor1.color1, + one = penum->icolor0.color1; + /* Invert the bit following the last valid data bit. */ + if ( endmask == 0x80 ) *endp = ~endp[-1] << 7; + else if ( *endp & (endmask << 1) ) *endp &= ~endmask; + else *endp |= endmask; + data = *psrc; + #define fill_run(color)\ + xni = fixed2int_var(xl);\ + if ( xni > xi )\ + { code = (*fill_proc)(dev, xi, iy, xni-xi, ih, color);\ + if ( code < 0 ) return code;\ + }\ + else if ( xni < xi )\ + { code = (*fill_proc)(dev, xni, iy, xi-xni, ih, color);\ + if ( code < 0 ) return code;\ + } + /* Pre-fill the scan line with the zero color. */ + /* This halves the number of fill_proc calls. */ + xl = xrun + (dxx * w); + fill_run(zero); + xl = xrun; + /* Loop invariants: data = *psrc; 0<=sbit<=7. */ + do + { /* Scan a run of zeros. */ + switch ( sbit ) + { + case 7: + w7: if ( data & 0x80 ) { sbit = 7; break; } xl += dxx; + case 6: + if ( data & 0x40 ) { sbit = 6; break; } xl += dxx; + case 5: + if ( data & 0x20 ) { sbit = 5; break; } xl += dxx; + case 4: + if ( data & 0x10 ) { sbit = 4; break; } xl += dxx; + case 3: + if ( data & 0x08 ) { sbit = 3; break; } xl += dxx; + case 2: + if ( data & 0x04 ) { sbit = 2; break; } xl += dxx; + case 1: + if ( data & 0x02 ) { sbit = 1; break; } xl += dxx; + case 0: + if ( data & 0x01 ) { sbit = 0; break; } xl += dxx; + while ( (data = *++psrc) == 0 ) xl += dxx_8; + goto w7; + } + if ( !(psrc < endp || sbit > endbit) ) + break; + xrun = xl, xi = fixed2int_var(xrun); + /* Scan a run of ones. */ + while ( (data >> sbit) & 1 ) + { xl += dxx; + if ( --sbit < 0 ) + { sbit = 7; + while ( (data = *++psrc) == 0xff ) + xl += dxx_8; + } + } + fill_run(one); + } while ( psrc < endp || sbit > endbit ); + #undef fill_run + return 1; + } + /* Rendering procedure for the general case of displaying a */ /* monochrome image, dealing with multiple bit-per-sample images, */ *************** *** 612,619 **** } fixed xl = xt; ! byte *psrc = buffer; byte *endp = buffer + w; fixed xrun = xt; /* x at start of run */ ! int run = *psrc; /* run value */ int htrun = /* halftone run value */ (masked ? 255 : -2); --- 668,675 ---- } fixed xl = xt; ! register const byte *psrc = buffer; byte *endp = buffer + w; fixed xrun = xt; /* x at start of run */ ! register byte run = *psrc; /* run value */ int htrun = /* halftone run value */ (masked ? 255 : -2); *************** *** 667,675 **** /* Fold the adjustment into xrun and xl, */ /* including the +0.5 for rounding. */ ! xrun = xrun - xa + float2fixed(0.5); ! xl = xl + xa + float2fixed(0.5); xa <<= 1; for ( ; ; ) ! { if ( *psrc++ != run ) { /* Fill the region between xrun and xl. */ int xi = fixed2int_var(xrun); --- 723,750 ---- /* Fold the adjustment into xrun and xl, */ /* including the +0.5 for rounding. */ ! xrun = xrun - xa + fixed_half; ! xl = xl + xa + fixed_half; xa <<= 1; for ( ; ; ) ! { /* Skip large constant regions quickly, */ ! /* but don't slow down transitions too much. */ ! while ( psrc[0] == run ) ! { if ( psrc[1] == run ) ! { if ( psrc[2] == run ) ! { if ( psrc[3] == run ) ! { psrc += 4, xl += dxx << 2; ! continue; ! } ! else ! psrc += 3, xl += (dxx << 1) + dxx; ! } ! else ! psrc += 2, xl += dxx << 1; ! } ! else ! psrc++, xl += dxx; ! break; ! } ! psrc++; { /* Fill the region between xrun and xl. */ int xi = fixed2int_var(xrun); *************** *** 719,722 **** --- 794,798 ---- pdevc->color1, pdevc->color2) ); + gp_check_interrupts(); } else *************** *** 734,855 **** } } - return 1; - } - - /* Rendering procedure for handling color images. */ - typedef union { struct { byte r, g, b, skip; } v; ulong all; } color_sample; - private int - image_render_color(gs_image_enum *penum, byte *buffer, uint w, int h) - { gs_state *pgs = penum->pgs; - fixed dxx = penum->fxx, dxy = penum->fxy, - dyx = penum->fyx, dyy = penum->fyy; - int skew = penum->skewed; - fixed xt = penum->xcur; - fixed ytf = penum->ycur; - int yt = penum->yci, iht = penum->hci; - gs_color rcolor; - gx_device_color devc1, devc2; - gx_device_color _ss *spdevc = &devc1; - gx_device_color _ss *spdevc_next = &devc2; - #define pdevc (gx_device_color *)spdevc - #define pdevc_next (gx_device_color *)spdevc_next - int spp = penum->spp; - fixed xl = xt; - byte *psrc = buffer; - fixed xrun = xt; /* x at start of run */ - int irun = fixed2int_var_rounded(xrun); /* int xrun */ - fixed yrun = ytf; /* y ditto */ - color_sample run; /* run value */ - color_sample next; /* next sample value */ - byte *bufend = buffer + w; - bufend[0] = ~bufend[-spp]; /* force end of run */ - #ifdef DEBUG - if ( gs_debug['b'] | gs_debug['B'] ) - dprintf5("[b]y=%d w=%d xt=%f yt=%f yb=%f\n", - penum->y, w, - fixed2float(xt), fixed2float(ytf), fixed2float(ytf + dyy)); - #endif - run.all = 0; - next.all = 0; - rcolor.red = rcolor.green = rcolor.blue = 0; - gx_color_from_rgb(&rcolor); - gx_color_render(&rcolor, pdevc, pgs); - while ( psrc <= bufend ) /* 1 extra iteration */ - /* to handle final run */ - { if ( spp == 4 ) /* cmyk */ - { switch ( psrc[3] ) - { - case 0: /* no black */ - next.v.r = ~psrc[0]; - next.v.g = ~psrc[1]; - next.v.b = ~psrc[2]; - break; - case 0xff: /* all black */ - next.v.r = next.v.g = next.v.b = 0; - break; - default: - { uint black = 0xff - psrc[3]; - /* The following is equivalent to */ - /* v * black / 0xff, without the divide. */ - register uint temp; - #define deduct_black(v)\ - (temp = (v) * black, (temp + (temp >> 8) + 1) >> 8) - next.v.r = deduct_black(0xff - psrc[0]); - next.v.g = deduct_black(0xff - psrc[1]); - next.v.b = deduct_black(0xff - psrc[2]); - #undef deduct_black - } - } - psrc += 4; - } - else /* rgb */ - { next.v.r = psrc[0]; - next.v.g = psrc[1]; - next.v.b = psrc[2]; - psrc += 3; - } - if ( next.all != run.all ) - { rcolor.red = gx_map_color_param_byte(pgs, next.v.r, red); - rcolor.green = gx_map_color_param_byte(pgs, next.v.g, green); - rcolor.blue = gx_map_color_param_byte(pgs, next.v.b, blue); - gx_color_from_rgb(&rcolor); - gx_color_render(&rcolor, pdevc_next, pgs); - /* Even though the supplied colors don't match, */ - /* the device colors might. */ - if ( devc1.color1 != devc2.color1 || - devc1.halftone_level != devc2.halftone_level || - (devc1.halftone_level && - devc1.color2 != devc2.color2) || - psrc > bufend /* force end of last run */ - ) - { /* Fill the region between */ - /* xrun/irun and xl */ - gx_device_color _ss *sptemp; - int code; - if ( skew ) - { /* Parallelogram */ - code = gz_fill_pgram_fixed(xrun, yrun, - xl - xrun, ytf - yrun, dyx, dyy, - pdevc, pgs); - xrun = xl; - yrun = ytf; - } - else - { /* Rectangle */ - int xi = irun; - int wi = (irun = fixed2int_var_rounded(xl)) - xi; - if ( wi < 0 ) xi += wi, wi = -wi; - code = gz_fill_rectangle(xi, yt, wi, iht, pdevc, pgs); - } - if ( code < 0 ) return code; - sptemp = spdevc; - spdevc = spdevc_next; - spdevc_next = sptemp; - } - run.all = next.all; - } - xl += dxx; - ytf += dxy; /* harmless if no skew */ - } return 1; } --- 810,813 ---- diff -rc2N gs241/gsimage2.c gs25/gsimage2.c *** gs241/gsimage2.c --- gs25/gsimage2.c Sat Aug 8 10:12:50 1992 *************** *** 0 **** --- 1,255 ---- + /* Copyright (C) 1992 Aladdin Enterprises. All rights reserved. + Distributed by Free Software Foundation, Inc. + + This file is part of Ghostscript. + + Ghostscript is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY. No author or distributor accepts responsibility + to anyone for the consequences of using it or for whether it serves any + particular purpose or works at all, unless he says so in writing. Refer + to the Ghostscript General Public License for full details. + + Everyone is granted permission to copy, modify and redistribute + Ghostscript, but only under the conditions described in the Ghostscript + General Public License. A copy of this license is supposed to have been + given to you along with Ghostscript so you can know your rights and + responsibilities. It should be in a file named COPYING. Among other + things, the copyright notice and this notice must be preserved on all + copies. */ + + /* gsimage2.c */ + /* Additional image procedures for Ghostscript library */ + /* This file is logically part of gsimage.c; we have split it out */ + /* to reduce the code working set. */ + #include "gx.h" + #include "memory_.h" + #include "gpcheck.h" + #include "gserrors.h" + #include "gxfixed.h" + #include "gxarith.h" + #include "gxmatrix.h" + #include "gspaint.h" + #include "gzstate.h" + #include "gzdevice.h" /* requires gsstate.h */ + #include "gzcolor.h" /* requires gxdevice.h */ + #include "gzpath.h" + #include "gxcpath.h" + #include "gxdevmem.h" + #include "gximage.h" + + /* ------ Unpacking procedures ------ */ + + void + image_unpack_1_spread(const gs_image_enum *penum, register byte *bufp, + register const byte *data, uint dsize, uint inpos) + { register int spread = penum->spread; + int left = dsize; + register const byte *map = &penum->map.to8[0]; + while ( left-- ) + { register uint b = *data++; + *bufp = map[b >> 7]; bufp += spread; + *bufp = map[(b >> 6) & 1]; bufp += spread; + *bufp = map[(b >> 5) & 1]; bufp += spread; + *bufp = map[(b >> 4) & 1]; bufp += spread; + *bufp = map[(b >> 3) & 1]; bufp += spread; + *bufp = map[(b >> 2) & 1]; bufp += spread; + *bufp = map[(b >> 1) & 1]; bufp += spread; + *bufp = map[b & 1]; bufp += spread; + } + } + + void + image_unpack_2_spread(const gs_image_enum *penum, register byte *bufp, + register const byte *data, uint dsize, uint inpos) + { register int spread = penum->spread; + int left = dsize; + register const byte *map = &penum->map.to8[0]; + while ( left-- ) + { register unsigned b = *data++; + *bufp = map[b >> 6]; bufp += spread; + *bufp = map[(b >> 4) & 3]; bufp += spread; + *bufp = map[(b >> 2) & 3]; bufp += spread; + *bufp = map[b & 3]; bufp += spread; + } + } + + void + image_unpack_8_spread(const gs_image_enum *penum, register byte *bufp, + register const byte *data, uint dsize, uint inpos) + { register int spread = penum->spread; + register int left = dsize; + register const byte *map = &penum->map.to8[0]; + while ( left-- ) + { *bufp = map[*data++]; bufp += spread; + } + } + + void + image_unpack_12(const gs_image_enum *penum, register byte *bufp, + register const byte *data, uint dsize, uint inpos) + { register int spread = penum->spread; + register int left = dsize; + register const byte *map = &penum->map.to8[0]; + /* We have to deal with the 3 cases of inpos % 3 separately. */ + /* (In fact, this is the only reason inpos is passed to */ + /* the unpacking procedures at all.) */ + /****** DOESN'T DO MAPPING RIGHT. ******/ + /* Let N = inpos / 3. */ + switch ( inpos % 3 ) + { + case 1: + /* bufp points to byte 2N, which was already filled */ + /* with the leftover byte from the previous call. */ + bufp += spread; + *bufp = *data++ << 4; + if ( !--left ) return; + case 2: + /* bufp points to byte 2N+1, which was half-filled */ + /* with the second leftover byte from the previous call. */ + *bufp = map[*bufp + (*data++ >> 4)]; + --left; + case 0: + /* Nothing special to do. */ + ; + } + /* Just drop the low 4 bits of each 12. */ + while ( left >= 3 ) + { *bufp = map[*data]; + bufp += spread; + *bufp = map[(data[1] << 4) + (data[2] >> 4)]; + bufp += spread; + data += 3; + } + switch ( left ) + { + case 2: /* dddddddd xxxxdddd */ + bufp[1] = data[1] << 4; + case 1: /* dddddddd */ + *bufp = map[*data]; + case 0: /* Nothing more to do. */ + ; + } + } + + /* ------ Rendering procedures ------ */ + + /* Rendering procedure for handling color images. */ + typedef union { struct { byte r, g, b, skip; } v; ulong all; } color_sample; + int + image_render_color(gs_image_enum *penum, byte *buffer, uint w, int h) + { gs_state *pgs = penum->pgs; + fixed dxx = penum->fxx, dxy = penum->fxy, + dyx = penum->fyx, dyy = penum->fyy; + int skew = penum->skewed; + fixed xt = penum->xcur; + fixed ytf = penum->ycur; + int yt = penum->yci, iht = penum->hci; + gs_color rcolor; + gx_device_color devc1, devc2; + gx_device_color _ss *spdevc = &devc1; + gx_device_color _ss *spdevc_next = &devc2; + #define pdevc ((gx_device_color *)spdevc) + #define pdevc_next ((gx_device_color *)spdevc_next) + int spp = penum->spp; + fixed xl = xt; + const byte *psrc = buffer; + fixed xrun = xt; /* x at start of run */ + int irun = fixed2int_var_rounded(xrun); /* int xrun */ + fixed yrun = ytf; /* y ditto */ + color_sample run; /* run value */ + color_sample next; /* next sample value */ + byte *bufend = buffer + w; + bufend[0] = ~bufend[-spp]; /* force end of run */ + if_debug5('b', "[b]y=%d w=%d xt=%f yt=%f yb=%f\n", + penum->y, w, + fixed2float(xt), fixed2float(ytf), fixed2float(ytf + dyy)); + run.all = 0; + next.all = 0; + rcolor.red = rcolor.green = rcolor.blue = 0; + gx_color_from_rgb(&rcolor); + gx_color_render(&rcolor, pdevc, pgs); + while ( psrc <= bufend ) /* 1 extra iteration */ + /* to handle final run */ + { if ( spp == 4 ) /* cmyk */ + { switch ( psrc[3] ) + { + case 0: /* no black */ + next.v.r = ~psrc[0]; + next.v.g = ~psrc[1]; + next.v.b = ~psrc[2]; + break; + case 0xff: /* all black */ + next.v.r = next.v.g = next.v.b = 0; + break; + default: + { uint black = 0xff - psrc[3]; + /* The following is equivalent to */ + /* v * black / 0xff, without the divide. */ + register uint temp; + #define deduct_black(v)\ + (temp = (v) * black, (temp + (temp >> 8) + 1) >> 8) + next.v.r = deduct_black(0xff - psrc[0]); + next.v.g = deduct_black(0xff - psrc[1]); + next.v.b = deduct_black(0xff - psrc[2]); + #undef deduct_black + } + } + psrc += 4; + } + else /* rgb */ + { next.v.r = psrc[0]; + next.v.g = psrc[1]; + next.v.b = psrc[2]; + psrc += 3; + } + if ( next.all != run.all ) + { rcolor.red = gx_map_color_param_byte(pgs, next.v.r, red); + rcolor.green = gx_map_color_param_byte(pgs, next.v.g, green); + rcolor.blue = gx_map_color_param_byte(pgs, next.v.b, blue); + gx_color_from_rgb(&rcolor); + gx_color_render(&rcolor, pdevc_next, pgs); + if_debug9('B', "[B]0x%x,0x%x,0x%x -> 0x%x,0x%x,0x%x -> %ld,%ld,%d\n", + next.v.r, next.v.g, next.v.b, + rcolor.red, rcolor.green, rcolor.blue, + pdevc_next->color1, pdevc_next->color2, + pdevc_next->halftone_level); + /* Even though the supplied colors don't match, */ + /* the device colors might. */ + if ( devc1.color1 != devc2.color1 || + devc1.halftone_level != devc2.halftone_level || + (devc1.halftone_level && + devc1.color2 != devc2.color2) || + psrc > bufend /* force end of last run */ + ) + { /* Fill the region between */ + /* xrun/irun and xl */ + gx_device_color _ss *sptemp; + int code; + if ( skew ) + { /* Parallelogram */ + code = gz_fill_pgram_fixed(xrun, yrun, + xl - xrun, ytf - yrun, dyx, dyy, + pdevc, pgs); + xrun = xl; + yrun = ytf; + } + else + { /* Rectangle */ + int xi = irun; + int wi = (irun = fixed2int_var_rounded(xl)) - xi; + if ( wi < 0 ) xi += wi, wi = -wi; + code = gz_fill_rectangle(xi, yt, wi, iht, pdevc, pgs); + gp_check_interrupts(); + } + if ( code < 0 ) return code; + sptemp = spdevc; + spdevc = spdevc_next; + spdevc_next = sptemp; + } + run.all = next.all; + } + xl += dxx; + ytf += dxy; /* harmless if no skew */ + } + return 1; + } diff -rc2N gs241/gsimpath.c gs25/gsimpath.c *** gs241/gsimpath.c --- gs25/gsimpath.c Tue Jun 23 12:51:56 1992 *************** *** 0 **** --- 1,183 ---- + /* Copyright (C) 1989, 1992 Aladdin Enterprises. All rights reserved. + Distributed by Free Software Foundation, Inc. + + This file is part of Ghostscript. + + Ghostscript is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY. No author or distributor accepts responsibility + to anyone for the consequences of using it or for whether it serves any + particular purpose or works at all, unless he says so in writing. Refer + to the Ghostscript General Public License for full details. + + Everyone is granted permission to copy, modify and redistribute + Ghostscript, but only under the conditions described in the Ghostscript + General Public License. A copy of this license is supposed to have been + given to you along with Ghostscript so you can know your rights and + responsibilities. It should be in a file named COPYING. Among other + things, the copyright notice and this notice must be preserved on all + copies. */ + + /* gsimpath.c */ + /* Image to outline conversion for Ghostscript library */ + #include "gx.h" + #include "gserrors.h" + #include "gsmatrix.h" + #include "gsstate.h" + #include "gspath.h" + + /* Define the state of the conversion process. */ + typedef struct { + /* The following are set at the beginning of the conversion. */ + gs_state *pgs; + const byte *data; /* image data */ + int width, height, raster; + /* The following are updated dynamically. */ + int dx, dy; /* X/Y increment of current run */ + int count; /* # of steps in current run */ + } status; + + /* Define the scaling for the path tracer. */ + /* It must be even. */ + #define outline_scale 4 + /* Define the length of the short strokes for turning corners. */ + #define step 1 + + /* Forward declarations */ + private int near get_pixel(P3(const status *, int, int)); + private int near trace_from(P4(status *, int, int, int)); + private int near add_dxdy(P4(status *, int, int, int)); + #define add_deltas(s, dx, dy, n)\ + if ( (code = add_dxdy(s, dx, dy, n)) < 0 ) return code + /* Append an outline derived from an image to the current path. */ + int + gs_imagepath(gs_state *pgs, int width, int height, const byte *data) + { status stat; + status *out = &stat; + int code, x, y; + /* Initialize the state. */ + stat.pgs = pgs; + stat.data = data; + stat.width = width; + stat.height = height; + stat.raster = (width + 7) / 8; + /* Trace the cells to form an outline. The trace goes in clockwise */ + /* order, always starting by going west along a bottom edge. */ + for ( y = height - 1; y >= 0; y-- ) + for ( x = width - 1; x >= 0; x-- ) + { if ( get_pixel(out, x, y) && !get_pixel(out, x, y - 1) && + (!get_pixel(out, x + 1, y) || get_pixel(out, x + 1, y - 1)) && + !trace_from(out, x, y, 1) + ) + { /* Found a starting point */ + stat.count = 0; + stat.dx = stat.dy = 0; + if ( (code = trace_from(out, x, y, 0)) < 0 ) + return code; + add_deltas(out, 0, 0, 1); /* force out last segment */ + if ( (code = gs_closepath(pgs)) < 0 ) + return code; + } + } + return 0; + } + + /* Get a pixel from the data. Return 0 if outside the image. */ + private int near + get_pixel(register const status *out, int x, int y) + { if ( x < 0 || x >= out->width || y < 0 || y >= out->height ) + return 0; + return (out->data[y * out->raster + (x >> 3)] >> (~x & 7)) & 1; + } + + /* Trace a path. If detect is true, don't draw, just return 1 if we ever */ + /* encounter a starting point whose x,y follows that of the initial point */ + /* in x-then-y scan order; if detect is false, actually draw the outline. */ + private int near + trace_from(register status *out, int x0, int y0, int detect) + { int x = x0, y = y0; + int dx = -1, dy = 0; /* initially going west */ + int part; /* how far along edge we are */ + int code; + if ( !detect ) + { part = (get_pixel(out, x + 1, y - 1) ? + outline_scale - step : step); + code = gs_moveto(out->pgs, + x + 1 - part / (float)outline_scale, + (float)y); + if ( code < 0 ) return code; + } + while ( 1 ) + { /* Relative to the current direction, */ + /* -dy,dx is at +90 degrees (counter-clockwise); */ + /* tx,ty is at +45 degrees; */ + /* ty,-tx is at -45 degrees (clockwise); */ + /* dy,-dx is at -90 degrees. */ + int tx = dx - dy, ty = dy + dx; + if ( get_pixel(out, x + tx, y + ty) ) + { /* Cell at 45 degrees is full, */ + /* go counter-clockwise. */ + if ( !detect ) + { /* If this is a 90 degree corner set at a */ + /* 45 degree angle, avoid backtracking. */ + if ( out->dx == ty && out->dy == -tx ) + { + #define half_scale (outline_scale / 2 - step) + out->count -= half_scale; + add_deltas(out, tx, ty, outline_scale / 2); + #undef half_scale + } + else + { add_deltas(out, dx, dy, step - part); + add_deltas(out, tx, ty, outline_scale - step); + } + part = outline_scale - step; + } + x += tx, y += ty; + dx = -dy, dy += tx; + } + else if ( !get_pixel(out, x + dx, y + dy) ) + { /* Cell straight ahead is empty, go clockwise. */ + if ( !detect ) + { add_deltas(out, dx, dy, outline_scale - step - part); + add_deltas(out, ty, -tx, step); + part = step; + } + dx = dy, dy -= ty; + } + else + { /* Neither of the above, go in same direction. */ + if ( !detect ) + { add_deltas(out, dx, dy, outline_scale); + } + x += dx, y += dy; + } + if ( dx == -step && dy == 0 && !(tx == -step && ty == -step) ) + { /* We just turned a corner and are going west, */ + /* so the previous pixel is a starting point pixel. */ + if ( x == x0 && y == y0 ) return 0; + if ( detect && (y > y0 || y == y0 && x > x0) ) + return 1; + } + } + } + + /* Add a (dx, dy) pair to the path being formed. */ + /* Accumulate successive segments in the same direction. */ + private int near + add_dxdy(register status *out, int dx, int dy, int count) + { if ( count != 0 ) + { if ( dx == out->dx && dy == out->dy ) + out->count += count; + else + { if ( out->count != 0 ) + { int code = gs_rlineto(out->pgs, + out->dx * out->count / (float)outline_scale, + out->dy * out->count / (float)outline_scale); + if ( code < 0 ) return code; + } + out->dx = dx, out->dy = dy; + out->count = count; + } + } + return 0; + } diff -rc2N gs241/gslp.ps gs25/gslp.ps *** gs241/gslp.ps Sat Feb 8 04:42:58 1992 --- gs25/gslp.ps Fri May 8 13:25:18 1992 *************** *** 180,186 **** BodyFont null eq { defaultBodyFont } { BodyFont } ifelse def /BFont BFont outfont ! /HFont ! HeadingFont null eq { defaultHeadingFont } { HeadingFont } ifelse def ! /HFont HFont outfont % Get the layout parameters. --- 180,189 ---- BodyFont null eq { defaultBodyFont } { BodyFont } ifelse def /BFont BFont outfont ! Headers ! { /HFont ! HeadingFont null eq { defaultHeadingFont } { HeadingFont } ifelse def ! /HFont HFont outfont ! } ! if % Get the layout parameters. *************** *** 288,292 **** /-l { 66 -L -B } def /-L { cvi /MaxLines exch def } def ! /-p { (w) file /OutFile exch def Outfile (%!\n) writestring } def /-P { cvi /PageFirst exch def } def /-Q { cvi /PageLast exch def } def --- 291,295 ---- /-l { 66 -L -B } def /-L { cvi /MaxLines exch def } def ! /-p { (w) file /OutFile exch def OutFile (%!\n) writestring } def /-P { cvi /PageFirst exch def } def /-Q { cvi /PageLast exch def } def diff -rc2N gs241/gsmain.c gs25/gsmain.c *** gs241/gsmain.c Thu Apr 16 16:43:40 1992 --- gs25/gsmain.c Mon Jul 27 07:51:20 1992 *************** *** 19,142 **** /* gsmain.c */ ! /* Framework for Ghostscript drivers */ ! #include "string_.h" #include "memory_.h" ! #include "gx.h" #include "gp.h" #include "gsmatrix.h" /* for gxdevice.h */ #include "gxdevice.h" ! #include "gxdevmem.h" ! ! /* ! * This routine provides the following standard services for parsing ! * a command line: ! * - setting debug flags (-A, -e, -E switches; -Z switch if debugging); ! * - passing other arguments and switches back to the caller. ! * ! * Calling convention: ! * gs_main(argc, argv, switch_proc, arg_proc) ! * Calls ! * switch_proc(&switch, rest_of_arg) for switches, ! * arg_proc(&arg, index) for non-switch args. ! * If switch_proc returns a negative value, gs_main prints an ! * "unknown switch" error message and aborts. ! * gs_main returns the number of non-switch args handed to arg_proc. ! */ /* Imported data */ ! extern int gs_alloc_debug; extern int gs_log_errors; ! extern gx_device *gx_device_list[]; ! void gs_exit(P1(int)); ! int ! gs_main(int argc, char *argv[], ! int (*switch_proc)(P2(char **, char *)), ! void (*arg_proc)(P2(char **, int))) ! { int argi = 1; ! int arg_count = 0; gs_log_errors = 0; - gs_out = stdout; - #ifdef DEBUG - gs_debug_out = stdout; /* Reset debugging flags */ memset(gs_debug, 0, 128); ! #endif ! /* If debugging is enabled, trace the device calls. */ ! #ifdef DEBUG ! { extern gx_device *gs_trace_device(P1(gx_device *)); ! extern gx_device_memory ! mem_mono_device, mem_mapped8_color_device, ! mem_true24_color_device, mem_true32_color_device; ! static gx_device_memory *mdevs[5] = ! { &mem_mono_device, &mem_mapped8_color_device, ! &mem_true24_color_device, &mem_true32_color_device, ! 0 ! }; ! extern gx_device gs_clist_device; /* gx_clist_device */ ! static gx_device *cldevs[2] = ! { &gs_clist_device, ! 0 ! }; ! gx_device **pdevs[4]; ! gx_device ***ppdev; ! gx_device **pdev; ! pdevs[0] = gx_device_list; ! pdevs[1] = (gx_device **)mdevs; ! pdevs[2] = cldevs; ! pdevs[3] = 0; ! /****** ! for ( ppdev = pdevs; *ppdev != 0; ppdev++ ) ! for ( pdev = *ppdev; *pdev != 0; pdev++ ) ! { gx_device *tdev = gs_trace_device(*pdev); ! if ( tdev == 0 ) ! { lprintf("Can't allocate traced device!\n"); ! gs_exit(1); ! } ! *pdev = tdev; ! } ! ******/ } ! #endif ! for ( ; argi < argc; argi++ ) ! { char **argp = &argv[argi]; ! char *arg = *argp; ! if ( *arg == '-' ) ! { switch ( *++arg ) ! { ! default: ! if ( (*switch_proc)(argp, arg + 1) < 0 ) ! printf("Unknown switch %s - ignoring\n", arg - 1); ! break; ! case 'A': ! gs_alloc_debug = 1; break; ! case 'e': ! gs_log_errors = 1; break; ! case 'E': ! gs_log_errors = 2; break; ! case 'Z': ! #ifdef DEBUG ! if ( !arg[1] ) ! { /* No options, set all flags */ ! memset(gs_debug, 0xff, 128); ! } ! else ! { while ( *++arg ) ! gs_debug[*arg & 127] = 0xff; ! } ! #else ! printf("Not a debugging configuration, -Z switch ignored\n"); ! #endif ! break; ! } ! } ! else ! (*arg_proc)(argp, arg_count++); } ! return arg_count; } /* Free all resources and exit. */ void gs_malloc_release(P0()); void file_close_all(P0()); --- 19,186 ---- /* gsmain.c */ ! /* Common support for Ghostscript front ends */ #include "memory_.h" ! #include "string_.h" ! #include "ghost.h" #include "gp.h" #include "gsmatrix.h" /* for gxdevice.h */ #include "gxdevice.h" ! #include "gserrors.h" ! #include "estack.h" ! #include "main.h" ! #include "ostack.h" ! #include "store.h" ! ! /* ------ Exported data ------ */ ! ! uint gs_memory_chunk_size = 20000; ! int gs_user_errors; ! ! /* File name search paths */ ! const char **gs_lib_paths; ! private int gs_lib_count; ! char *gs_lib_env_path; /* Imported data */ ! /* Configuration information imported from gconfig.c. */ ! extern const char *gs_lib_default_path; ! extern const char *gs_init_file; ! extern ref gs_init_file_array[]; ! /* Imported from gsmisc.c */ extern int gs_log_errors; ! extern FILE *gs_debug_out; ! /* ------ Initialization ------ */ ! /* Remember how much initialization has been done. */ ! private int init1_done, init2_done; ! ! /* A handy way to declare and execute an initialization procedure: */ ! #define call_init(proc)\ ! { extern void proc(P0()); proc(); } ! ! /* Initialization to be done before anything else. */ ! void ! gs_init0(FILE *in, FILE *out, FILE *err, int max_lib_paths) ! { /* Set the Ghostscript versions of stdin/out/err. */ ! gs_stdin = in; ! gs_stdout = out; ! gs_stderr = err; ! gs_debug_out = gs_stdout; ! /* Do platform-dependent initialization. */ ! /* We have to do this as the very first thing, */ ! /* because it detects attempts to run 80N86 executables (N>0) */ ! /* on incompatible processors. */ ! gp_init(); ! /* Initialize the file search paths */ ! gs_lib_env_path = 0; ! gs_lib_paths = ! (const char **)gs_malloc(max_lib_paths + 3, sizeof(char *), ! "gs_lib_paths array"); ! gs_lib_count = 0; ! gs_user_errors = 1; gs_log_errors = 0; /* Reset debugging flags */ memset(gs_debug, 0, 128); ! init1_done = init2_done = 0; ! } ! ! /* Initialization to be done before constructing any objects. */ ! void ! gs_init1() ! { if ( !init1_done ) ! { alloc_init(gs_malloc, gs_free, gs_memory_chunk_size); ! call_init(name_init) ! call_init(obj_init) /* requires name_init */ ! call_init(scan_init) /* ditto */ ! init1_done = 1; ! } ! } ! ! /* Initialization to be done before running any files. */ ! void ! gs_init2() ! { gs_init1(); ! if ( !init2_done ) ! { int code, exit_code; ! call_init(gs_init) ! call_init(zop_init) ! interp_init(1); /* requires obj_init */ ! call_init(op_init) /* requires obj_init, scan_init */ ! /* Set up the array of additional initialization files. */ ! { ref *ifp = gs_init_file_array; ! ref ifa; ! for ( ; ifp->value.bytes != 0; ifp++ ) ! r_set_size(ifp, strlen((const char *)ifp->value.bytes)); ! make_tasv(&ifa, t_array, a_readonly, ! ifp - gs_init_file_array, refs, ! gs_init_file_array); ! initial_enter_name("INITFILES", &ifa); ! } ! /* Execute the standard initialization file. */ ! code = gs_run_file(gs_init_file, gs_user_errors, &exit_code); ! if ( code < 0 ) ! { if ( code != gs_error_Fatal ) ! gs_debug_dump_stack(code); ! gs_exit((exit_code ? exit_code : 2)); ! } ! init2_done = 1; } ! } ! ! /* Add a library search path to the list. */ ! void ! gs_add_lib_path(const char *lpath) ! { gs_lib_paths[gs_lib_count] = lpath; ! gs_lib_count++; ! } ! ! /* ------ Execution ------ */ ! ! /* Complete the list of library search paths. */ ! private void ! set_lib_paths() ! { const char **ppath = &gs_lib_paths[gs_lib_count]; ! if ( gs_lib_env_path != 0 ) *ppath++ = gs_lib_env_path; ! if ( gs_lib_default_path != 0 ) *ppath++ = gs_lib_default_path; ! *ppath = 0; ! } ! ! /* Open and execute a file */ ! private int ! run_open(const char *file_name, ref *pfile) ! { /* This is a separate procedure only to avoid tying up */ ! /* extra stack space while running the file. */ ! #define maxfn 200 ! byte fn[maxfn]; ! uint len; ! return lib_file_open(file_name, strlen(file_name), fn, maxfn, ! &len, pfile); ! } ! int ! gs_run_file(const char *file_name, int user_errors, int *pexit_code) ! { ref initial_file; ! set_lib_paths(); ! if ( run_open(file_name, &initial_file) < 0 ) ! { eprintf1("Can't find initialization file %s\n", file_name); ! return_error(gs_error_Fatal); } ! r_set_attrs(&initial_file, a_execute + a_executable); ! return gs_interpret(&initial_file, user_errors, pexit_code); } + int + gs_run_string(const char *str, int user_errors, int *pexit_code) + { ref stref; + set_lib_paths(); + make_tasv(&stref, t_string, a_executable + a_readonly, + strlen(str), const_bytes, (byte *)str); + return gs_interpret(&stref, gs_user_errors, pexit_code); + } + + /* ------ Termination ------ */ + /* Free all resources and exit. */ + extern gx_device *gx_device_list[]; void gs_malloc_release(P0()); void file_close_all(P0()); *************** *** 143,150 **** int gs_closedevice(P1(gx_device *)); void gp_exit(P0()); ! void ! gs_exit(int code) { gx_device **pdev = gx_device_list; ! if ( code != 0 ) fflush(stderr); /* in case of error exit */ for ( ; *pdev != 0; pdev++ ) gs_closedevice(*pdev); --- 187,193 ---- int gs_closedevice(P1(gx_device *)); void gp_exit(P0()); ! void gs_finit() { gx_device **pdev = gx_device_list; ! fflush(stderr); /* in case of error exit */ for ( ; *pdev != 0; pdev++ ) gs_closedevice(*pdev); *************** *** 155,162 **** /* Do platform-specific cleanup. */ gp_exit(); exit(code); } ! /* ------ Debugging routines ------ */ /* Log an error return */ --- 198,225 ---- /* Do platform-specific cleanup. */ gp_exit(); + } + void + gs_exit(int code) + { gs_finit(); exit(code); } ! /* ------ Debugging ------ */ ! ! /* Debugging code */ ! extern void debug_print_ref(P1(const ref *)); ! extern void debug_dump_refs(P3(const ref *, uint, const char *)); ! extern ref error_object; ! ! /* Dump the stacks after interpretation */ ! void ! gs_debug_dump_stack(int code) ! { zflush(osp); /* force out buffered output */ ! dprintf1("\nUnexpected interpreter error %d!\nError object: ", code); ! debug_print_ref(&error_object); ! dputc('\n'); ! debug_dump_refs(osbot, osp + 1 - osbot, "Operand stack"); ! debug_dump_refs(esbot, esp + 1 - esbot, "Execution stack"); ! } /* Log an error return */ diff -rc2N gs241/gsmatrix.c gs25/gsmatrix.c *** gs241/gsmatrix.c Fri Mar 6 01:49:20 1992 --- gs25/gsmatrix.c Sun May 24 04:21:12 1992 *************** *** 273,277 **** /* Transform a point with a fixed-point result. */ int ! gs_point_transform2fixed(register gs_matrix_fixed *pmat, floatp x, floatp y, gs_fixed_point *ppt) { ppt->x = float2fixed(x * pmat->xx) + pmat->tx_fixed; --- 273,277 ---- /* Transform a point with a fixed-point result. */ int ! gs_point_transform2fixed(register const gs_matrix_fixed *pmat, floatp x, floatp y, gs_fixed_point *ppt) { ppt->x = float2fixed(x * pmat->xx) + pmat->tx_fixed; *************** *** 286,290 **** /* Transform a distance with a fixed-point result. */ int ! gs_distance_transform2fixed(register gs_matrix_fixed *pmat, floatp dx, floatp dy, gs_fixed_point *ppt) { ppt->x = float2fixed(dx * pmat->xx); --- 286,290 ---- /* Transform a distance with a fixed-point result. */ int ! gs_distance_transform2fixed(register const gs_matrix_fixed *pmat, floatp dx, floatp dy, gs_fixed_point *ppt) { ppt->x = float2fixed(dx * pmat->xx); diff -rc2N gs241/gsmatrix.h gs25/gsmatrix.h *** gs241/gsmatrix.h Fri Mar 6 01:49:18 1992 --- gs25/gsmatrix.h Thu May 14 03:55:32 1992 *************** *** 37,43 **** long _tx /*skip*/; float tx;\ long _ty /*skip*/; float ty ! typedef struct gs_matrix_s { _matrix_body; ! } gs_matrix; /* Macro for initializing constant matrices */ #define constant_matrix_body(xx, xy, yx, yy, tx, ty)\ --- 37,47 ---- long _tx /*skip*/; float tx;\ long _ty /*skip*/; float ty ! struct gs_matrix_s { _matrix_body; ! }; ! #ifndef gs_matrix_DEFINED ! # define gs_matrix_DEFINED ! typedef struct gs_matrix_s gs_matrix; ! #endif /* Macro for initializing constant matrices */ #define constant_matrix_body(xx, xy, yx, yy, tx, ty)\ diff -rc2N gs241/gsmisc.c gs25/gsmisc.c *** gs241/gsmisc.c Thu Apr 16 14:11:40 1992 --- gs25/gsmisc.c Wed Aug 12 18:13:58 1992 *************** *** 20,23 **** --- 20,24 ---- /* gsmisc.c */ /* Miscellaneous utilities for Ghostscript library */ + #include #include "gx.h" #include "malloc_.h" *************** *** 24,30 **** #include "memory_.h" ! /* Ghostscript writes to gs_out instead of stdout, */ ! /* and writes debugging output to gs_debug_out. */ ! FILE *gs_out; /* We define gs_debug and gs_debug_out even if DEBUG isn't defined, */ /* so that we can compile individual modules with DEBUG set. */ --- 25,31 ---- #include "memory_.h" ! /* Define private replacements for stdin, stdout, and stderr. */ ! FILE *gs_stdin, *gs_stdout, *gs_stderr; ! /* Ghostscript writes debugging output to gs_debug_out. */ /* We define gs_debug and gs_debug_out even if DEBUG isn't defined, */ /* so that we can compile individual modules with DEBUG set. */ *************** *** 154,163 **** } ! /* Swap even and odd bytes. */ /* This routine may be supplanted by assembly code. */ #if !USE_ASM ! #undef memswab /* see memory_.h */ void ! memswab(const char *src, char *dest, int count) { register const uint *sptr = (const uint *)src; register uint *dptr = (uint *)dest; --- 155,165 ---- } ! /* Swap bytes in 16-bit words. */ /* This routine may be supplanted by assembly code. */ + /* src and dest must be 16-bit aligned; count must be even. */ #if !USE_ASM ! #undef memswab2 /* see memory_.h */ void ! memswab2(const char *src, char *dest, int count) { register const uint *sptr = (const uint *)src; register uint *dptr = (uint *)dest; *************** *** 165,171 **** register uint w; for ( x = count >> 3; --x >= 0; ) ! { w = *sptr; #if arch_ints_are_short ! *dptr = (w >> 8) + (w << 8); w = sptr[1]; dptr[1] = (w >> 8) + (w << 8); --- 167,173 ---- register uint w; for ( x = count >> 3; --x >= 0; ) ! { w = sptr[0]; #if arch_ints_are_short ! dptr[0] = (w >> 8) + (w << 8); w = sptr[1]; dptr[1] = (w >> 8) + (w << 8); *************** *** 176,180 **** sptr += 4, dptr += 4; #else ! *dptr = ((w << 8) & 0xff00ff00) + ((w >> 8) & 0x00ff00ff); w = sptr[1]; dptr[1] = ((w << 8) & 0xff00ff00) + ((w >> 8) & 0x00ff00ff); --- 178,182 ---- sptr += 4, dptr += 4; #else ! dptr[0] = ((w << 8) & 0xff00ff00) + ((w >> 8) & 0x00ff00ff); w = sptr[1]; dptr[1] = ((w << 8) & 0xff00ff00) + ((w >> 8) & 0x00ff00ff); *************** *** 196,199 **** --- 198,240 ---- ; } + } + #endif /* !USE_ASM */ + + /* Swap bytes in 32-bit words. */ + /* src and dest must be 32-bit aligned; count must be 0 mod 4. */ + /* This routine may be supplanted by assembly code. */ + #if !USE_ASM + #undef memswab4 /* see memory_.h */ + void + memswab4(const char *src, char *dest, int count) + { register const ulong *sptr = (const ulong *)src; + register ulong *dptr = (ulong *)dest; + register int x; + register uint w0, w1; + for ( x = count >> 3; --x >= 0; ) + { w0 = sptr[0], w1 = sptr[1]; + #if arch_ints_are_short + dptr[0] = (w1 >> 8) + (w1 << 8); + dptr[1] = (w0 >> 8) + (w0 << 8); + w0 = sptr[2], w1 = sptr[3]; + dptr[2] = (w1 >> 8) + (w1 << 8); + dptr[3] = (w0 >> 8) + (w0 << 8); + sptr += 4, dptr += 4; + #else + dptr[0] = + (w0 << 24) + ((w0 & 0xff00) << 8) + + ((w0 >> 8) & 0xff00) + (w0 >> 24); + dptr[1] = + (w1 << 24) + ((w1 & 0xff00) << 8) + + ((w1 >> 8) & 0xff00) + (w1 >> 24); + sptr += 2, dptr += 2; + #endif + } + if ( count & 4 ) + { w0 = ((const ushort *)sptr)[0]; + w1 = ((const ushort *)sptr)[1]; + ((ushort *)dptr)[0] = (w1 >> 8) + (w1 << 8); + ((ushort *)dptr)[1] = (w0 >> 8) + (w0 << 8); + } } #endif /* !USE_ASM */ diff -rc2N gs241/gspaint.c gs25/gspaint.c *** gs241/gspaint.c Mon Nov 25 12:24:16 1991 --- gs25/gspaint.c Fri Jun 12 02:51:22 1992 *************** *** 1,3 **** ! /* Copyright (C) 1989, 1990 Aladdin Enterprises. All rights reserved. Distributed by Free Software Foundation, Inc. --- 1,3 ---- ! /* Copyright (C) 1989, 1992 Aladdin Enterprises. All rights reserved. Distributed by Free Software Foundation, Inc. *************** *** 21,24 **** --- 21,25 ---- /* Painting procedures for GhostScript library */ #include "gx.h" + #include "gpcheck.h" #include "gserrors.h" #include "gxfixed.h" *************** *** 39,42 **** --- 40,44 ---- gx_device *dev = pdev->info; (*dev->procs->fill_rectangle)(dev, 0, 0, dev->width, dev->height, pdev->white); + gp_check_interrupts(); return 0; } *************** *** 108,167 **** *pgs->path = spath; return 0; - } - - /* Render a sampled image */ - int - gs_colorimage(gs_state *pgs, int width, int height, int bps, int spp, - gs_matrix *pmat, byte *data) - { gs_image_enum *penum = - (gs_image_enum *)gs_malloc(1, gs_image_enum_sizeof, "gs_[color]image"); - int code; - if ( penum == 0 ) return_error(gs_error_VMerror); - if ( (code = gs_image_init(penum, pgs, width, height, bps, spp, pmat)) < 0 ) - { gs_free((char *)penum, 1, gs_image_enum_sizeof, "gs_[color]image"); - return code; - } - if ( spp > 0 ) - { uint size = - (((uint)width * bps * spp + 7) >> 3) * (uint)height; - code = gs_image_next(penum, data, size); - } - else - { /* Deliver the colors separately */ - uint plane_size = - (((uint)width * bps + 7) >> 3) * (uint)height; - byte *plane_data = data; - int count = spp; - do - { code = gs_image_next(penum, plane_data, plane_size); - if ( code < 0 ) return code; - plane_data += plane_size; - } - while ( ++count ); - } - gs_free((char *)penum, 1, gs_image_enum_sizeof, "gs_[color]image"); - return (code < 0 ? code : 0); - } - int - gs_image(gs_state *pgs, int width, int height, int bps, - gs_matrix *pmat, byte *data) - { return gs_colorimage(pgs, width, height, bps, 1, pmat, data); - } - - /* Render a mask */ - int - gs_imagemask(gs_state *pgs, int width, int height, int invert, - gs_matrix *pmat, byte *data, int adjust) - { gs_image_enum *penum = - (gs_image_enum *)gs_malloc(1, gs_image_enum_sizeof, "gs_imagemask"); - int code; - uint size = (((uint)width + 7) >> 3) * (uint)height; - if ( penum == 0 ) return_error(gs_error_VMerror); - if ( (code = gs_imagemask_init(penum, pgs, width, height, invert, pmat, adjust)) < 0 ) - { gs_free((char *)penum, 1, gs_image_enum_sizeof, "gs_imagemask"); - return code; - } - code = gs_image_next(penum, data, size); - gs_free((char *)penum, 1, gs_image_enum_sizeof, "gs_imagemask"); - return (code < 0 ? code : 0); } --- 110,112 ---- diff -rc2N gs241/gspaint.h gs25/gspaint.h *** gs241/gspaint.h Sun May 19 17:23:26 1991 --- gs25/gspaint.h Thu May 28 12:40:42 1992 *************** *** 1,3 **** ! /* Copyright (C) 1989, 1990 Aladdin Enterprises. All rights reserved. Distributed by Free Software Foundation, Inc. --- 1,3 ---- ! /* Copyright (C) 1989, 1992 Aladdin Enterprises. All rights reserved. Distributed by Free Software Foundation, Inc. *************** *** 28,39 **** gs_stroke(P1(gs_state *)); ! /* Image painting */ ! int gs_colorimage(P7(gs_state *, int, int, int, int, gs_matrix *, byte *)), ! gs_image(P6(gs_state *, int, int, int, gs_matrix *, byte *)), ! gs_imagemask(P7(gs_state *, int, int, int, gs_matrix *, byte *, int)); ! /* Enumeration-style image painting */ typedef struct gs_image_enum_s gs_image_enum; extern const uint gs_image_enum_sizeof; ! int gs_image_init(P7(gs_image_enum *, gs_state *, int, int, int, int, gs_matrix *)), ! gs_imagemask_init(P7(gs_image_enum *, gs_state *, int, int, int, gs_matrix *, int)), ! gs_image_next(P3(gs_image_enum *, byte *, uint)); --- 28,44 ---- gs_stroke(P1(gs_state *)); ! /* Image painting. This is done in an enumeration style: */ ! /* the client initializes an enumerator, then supplies data incrementally. */ typedef struct gs_image_enum_s gs_image_enum; extern const uint gs_image_enum_sizeof; ! int gs_image_init(P8(gs_image_enum *penum, gs_state *pgs, ! int width, int height, int bits_per_component, ! int components_per_pixel, const float *decode, ! gs_matrix *pmat)), ! gs_imagemask_init(P7(gs_image_enum *penum, gs_state *pgs, ! int width, int height, int invert, ! gs_matrix *pmat, int adjust)), ! gs_image_next(P3(gs_image_enum *penum, byte *dbytes, uint dsize)); ! ! /* Image tracing */ ! int gs_imagepath(P4(gs_state *, int, int, const byte *)); diff -rc2N gs241/gspath2.c gs25/gspath2.c *** gs241/gspath2.c Tue Mar 24 03:26:40 1992 --- gs25/gspath2.c Sun Aug 2 13:53:10 1992 *************** *** 36,41 **** /* Path enumeration structure */ struct gs_path_enum_s { ! segment *pseg; const gs_state *pgs; }; --- 36,42 ---- /* Path enumeration structure */ struct gs_path_enum_s { ! const segment *pseg; const gs_state *pgs; + int moveto_done; /* have we reported a final moveto yet? */ }; *************** *** 50,54 **** int code; if ( !pgs->path->curve_count ) return 0; /* no curves */ ! code = gx_path_flatten(pgs->path, &fpath, pgs->flatness); if ( code < 0 ) return code; gx_path_release(pgs->path); --- 51,55 ---- int code; if ( !pgs->path->curve_count ) return 0; /* no curves */ ! code = gx_path_flatten(pgs->path, &fpath, pgs->flatness, 0); if ( code < 0 ) return code; gx_path_release(pgs->path); *************** *** 60,64 **** gs_reversepath(gs_state *pgs) { gx_path rpath; ! int code = gx_path_reverse(pgs->path, &rpath); if ( code < 0 ) return code; gx_path_release(pgs->path); --- 61,65 ---- gs_reversepath(gs_state *pgs) { gx_path rpath; ! int code = gx_path_copy_reversed(pgs->path, &rpath, 1); if ( code < 0 ) return code; gx_path_release(pgs->path); *************** *** 88,93 **** void gs_path_enum_init(gs_path_enum *penum, const gs_state *pgs) ! { penum->pseg = (segment *)pgs->path->first_subpath; penum->pgs = pgs; } --- 89,95 ---- void gs_path_enum_init(gs_path_enum *penum, const gs_state *pgs) ! { penum->pseg = (const segment *)pgs->path->first_subpath; penum->pgs = pgs; + penum->moveto_done = 0; } *************** *** 97,105 **** int gs_path_enum_next(gs_path_enum *penum, gs_point ppts[3]) ! { segment *pseg = penum->pseg; const gs_state *pgs = penum->pgs; gs_point pt; int code; ! if ( pseg == 0 ) return 0; /* finished */ penum->pseg = pseg->next; if ( pseg->type == s_line_close ) --- 99,129 ---- int gs_path_enum_next(gs_path_enum *penum, gs_point ppts[3]) ! { const segment *pseg = penum->pseg; const gs_state *pgs = penum->pgs; gs_point pt; int code; ! if ( pseg == 0 ) ! { /* We've enumerated all the segments, but there might be */ ! /* a trailing moveto. */ ! const gx_path *ppath = pgs->path; ! const subpath *psub = ppath->current_subpath; ! if ( !ppath->subpath_open && ppath->position_valid && ! !penum->moveto_done && (!psub->closed || ! /* If the last subpath was closed, we can't know */ ! /* if it was followed by a move to the same point. */ ! /* Just compare the coordinates and hope we're right. */ ! psub->last->pt.x != ppath->position.x || ! psub->last->pt.y != ppath->position.y) ! ) ! { penum->moveto_done = 1; ! if ( (code = gs_itransform(pgs, ! fixed2float(ppath->position.x), ! fixed2float(ppath->position.y), ! &ppts[0])) < 0 ) ! return code; ! return gs_pe_moveto; ! } ! return 0; ! } penum->pseg = pseg->next; if ( pseg->type == s_line_close ) *************** *** 117,121 **** return gs_pe_lineto; case s_curve: ! #define pcurve ((curve_segment *)pseg) if ( (code = gs_itransform(pgs, fixed2float(pcurve->p1.x), --- 141,145 ---- return gs_pe_lineto; case s_curve: ! #define pcurve ((const curve_segment *)pseg) if ( (code = gs_itransform(pgs, fixed2float(pcurve->p1.x), *************** *** 130,134 **** default: lprintf1("bad type %x in gs_path_enum_next!\n", pseg->type); ! gs_exit(1); } } --- 154,158 ---- default: lprintf1("bad type %x in gs_path_enum_next!\n", pseg->type); ! return_error(gs_error_Fatal); } } *************** *** 141,145 **** int code = gx_cpath_path(pgs->clip_path, &path); if ( code < 0 ) return code; ! return gx_path_copy(&path, pgs->path); } --- 165,169 ---- int code = gx_cpath_path(pgs->clip_path, &path); if ( code < 0 ) return code; ! return gx_path_copy(&path, pgs->path, 1); } *************** *** 169,172 **** --- 193,202 ---- (dev->height / dev->y_pixels_per_inch - dev->t_margin) * 72, &box.q); + /* Make sure the clipping rectangle falls entirely */ + /* in non-negative coordinates. */ + if ( box.p.x < 0 ) box.p.x = 0; + if ( box.p.y < 0 ) box.p.y = 0; + if ( box.q.x < 0 ) box.q.x = 0; + if ( box.q.y < 0 ) box.p.y = 0; } return gx_clip_to_rectangle(pgs, &box); *************** *** 186,192 **** common_clip(gs_state *pgs, int rule) { gx_path fpath; ! int code = gx_path_flatten(pgs->path, &fpath, pgs->flatness); if ( code < 0 ) return code; code = gx_cpath_intersect(pgs, pgs->clip_path, &fpath, rule); if ( code < 0 ) return code; return set_clip_path(pgs, pgs->clip_path, rule); --- 216,223 ---- common_clip(gs_state *pgs, int rule) { gx_path fpath; ! int code = gx_path_flatten(pgs->path, &fpath, pgs->flatness, 0); if ( code < 0 ) return code; code = gx_cpath_intersect(pgs, pgs->clip_path, &fpath, rule); + if ( code != 1 ) gx_path_release(&fpath); if ( code < 0 ) return code; return set_clip_path(pgs, pgs->clip_path, rule); diff -rc2N gs241/gssetmod.bat gs25/gssetmod.bat *** gs241/gssetmod.bat Fri Apr 17 14:11:28 1992 --- gs25/gssetmod.bat Tue Aug 11 18:32:32 1992 *************** *** 1,3 **** @echo off ! echo @rem This file was automatically generated by Ghostscript (gssetmod). >%1.dev gsaddmod %1 -obj %2 %3 %4 %5 %6 %7 %8 %9 --- 1,12 ---- @echo off ! echogs @echo off >%1.dev ! echo rem This file was automatically generated by Ghostscript (gssetmod). >>%1.dev ! if exist %1.d_n erase %1.d_n ! if exist %1.d_o erase %1.d_o ! if exist %1.d_v erase %1.d_v ! if exist %1.d_w erase %1.d_w ! echo if exist %1.d_n copy /b _temp_.dh+%1.d_n >>%1.dev ! echo if exist %1.d_o copy /b _temp_.dob+%1.d_o >>%1.dev ! echo if exist %1.d_v copy /b _temp_.dop+%1.d_v >>%1.dev ! echo if exist %1.d_w copy /b _temp_.dow+%1.d_w >>%1.dev gsaddmod %1 -obj %2 %3 %4 %5 %6 %7 %8 %9 diff -rc2N gs241/gsstate.c gs25/gsstate.c *** gs241/gsstate.c Tue Apr 7 15:40:12 1992 --- gs25/gsstate.c Mon Jun 8 17:20:42 1992 *************** *** 72,75 **** --- 72,76 ---- pgs->in_cachedevice = pgs->in_charpath = 0; pgs->level = 0; + pgs->client_data = 0; if ( gs_initgraphics(pgs) < 0 ) { /* Something went very wrong */ *************** *** 79,82 **** --- 80,97 ---- } + /* Set the client data in a graphics state. */ + /* This should only be done to a newly created state. */ + void + gs_state_set_client(gs_state *pgs, char/*void*/ *pdata, const gs_state_client_procs *pprocs) + { pgs->client_data = pdata; + pgs->client_procs = *pprocs; + } + + /* Get the client data from a graphics state. */ + char/*void*/ * + gs_state_client_data(gs_state *pgs) + { return pgs->client_data; + } + /* Free a graphics state */ int *************** *** 100,105 **** --- 115,127 ---- } copy_gstate_contents(pgs, pnew); + /* Make pnew, not pgs, have the newly-allocated client data. */ + { char/*void*/ *pdata = pgs->client_data; + pgs->client_data = pnew->client_data; + pnew->client_data = pdata; + } pgs->saved = pnew; pgs->level++; + if_debug2('g', "[g]save -> 0x%lx, level = %d\n", + (ulong)pnew, pgs->level); return 0; } *************** *** 109,115 **** --- 131,147 ---- gs_grestore(gs_state *pgs) { gs_state *saved = pgs->saved; + char/*void*/ *pdata = pgs->client_data; + if_debug2('g', "[g]restore 0x%lx, level was %d\n", + (ulong)saved, pgs->level); if ( !saved ) return gs_gsave(pgs); /* shouldn't happen */ + pgs->client_data = 0; /* don't free it */ free_gstate_contents(pgs); *pgs = *saved; + if ( pgs->client_data != 0 ) + { if ( pdata != 0 ) + (*pgs->client_procs.copy)(pdata, pgs->client_data); + (*pgs->client_procs.free)(pgs->client_data, &pgs->memory_procs); + } + pgs->client_data = pdata; free_struct(pgs, saved, "gs_grestore"); return (pgs->saved == 0 ? gs_gsave(pgs) : 0); *************** *** 153,156 **** --- 185,189 ---- gcopy(transfer); gcopy(device); + gcopy(client_data); #undef gcopy copy_gstate_contents(pto, pgs); *************** *** 190,193 **** --- 223,229 ---- p2->saved = p1->saved; p1->saved = temp.saved; + /* Restore the client data pointers. */ + p2->client_data = p1->client_data; + p1->client_data = temp.client_data; } *************** *** 251,255 **** *pgs = *pold; else ! pgs->transfer = 0; pgs->memory_procs.alloc = palloc; pgs->memory_procs.free = pfree; --- 287,292 ---- *pgs = *pold; else ! pgs->transfer = 0, ! pgs->client_data = 0; pgs->memory_procs.alloc = palloc; pgs->memory_procs.free = pfree; *************** *** 284,287 **** --- 321,328 ---- galloc(device, device, ud); #undef galloc + if ( pgs->client_data != 0 ) + { if ( (pgs->client_data = (*pgs->client_procs.alloc)(&pgs->memory_procs)) == 0 ) + goto ucd; + } pgs->device_is_shared = 0; return 0; *************** *** 288,291 **** --- 329,333 ---- /* Undo partial allocations if an allocation failed. */ #define gunalloc(element) free_struct(pgs, pgs->element, cname) + ucd: gunalloc(device); ud: gunalloc(transfer); ut: gunalloc(dev_color); *************** *** 306,309 **** --- 348,353 ---- gx_cpath_release(pgs->clip_path); gx_path_release(pgs->path); + if ( pgs->client_data != 0 ) + (*pgs->client_procs.free)(pgs->client_data, &pgs->memory_procs); #define gfree(element)\ (*pfree)((char *)pgs->element, 1, sizeof(*pgs->element), cname) *************** *** 344,347 **** --- 388,393 ---- gcopy(device); #undef gcopy + if ( pfrom->client_data != 0 ) + (*pfrom->client_procs.copy)(pto->client_data, pfrom->client_data); gx_path_share(pto->path); gx_cpath_share(pto->clip_path); diff -rc2N gs241/gsstate.h gs25/gsstate.h *** gs241/gsstate.h Tue Apr 7 16:18:42 1992 --- gs25/gsstate.h Mon Jun 8 01:44:28 1992 *************** *** 1,3 **** ! /* Copyright (C) 1989, 1990, 1991 Aladdin Enterprises. All rights reserved. Distributed by Free Software Foundation, Inc. --- 1,3 ---- ! /* Copyright (C) 1989, 1992 Aladdin Enterprises. All rights reserved. Distributed by Free Software Foundation, Inc. *************** *** 61,70 **** int gs_copyscanlines(P6(gx_device *, int, byte *, uint, int *, uint *)); gx_device * gs_getdevice(P1(int)); ! int gs_copydevice(P3(gx_device **, gx_device *, proc_alloc_t)); ! int gs_makeimagedevice(P7(gx_device **, gs_matrix *, uint, uint, byte *, int, proc_alloc_t)); void gs_nulldevice(P1(gs_state *)); int gs_setdevice(P2(gs_state *, gx_device *)); ! gx_device * gs_currentdevice(P1(gs_state *)); ! const char * gs_devicename(P1(gx_device *)); void gs_deviceinitialmatrix(P2(gx_device *, gs_matrix *)); int gs_closedevice(P1(gx_device *)); --- 61,70 ---- int gs_copyscanlines(P6(gx_device *, int, byte *, uint, int *, uint *)); gx_device * gs_getdevice(P1(int)); ! int gs_copydevice(P3(gx_device **, const gx_device *, proc_alloc_t)); ! int gs_makeimagedevice(P7(gx_device **, const gs_matrix *, uint, uint, const byte *, int, proc_alloc_t)); void gs_nulldevice(P1(gs_state *)); int gs_setdevice(P2(gs_state *, gx_device *)); ! gx_device * gs_currentdevice(P1(const gs_state *)); ! const char * gs_devicename(P1(const gx_device *)); void gs_deviceinitialmatrix(P2(gx_device *, gs_matrix *)); int gs_closedevice(P1(gx_device *)); *************** *** 102,103 **** --- 102,115 ---- int gs_screen_currentpoint(P2(gs_screen_enum *, gs_point *)); int gs_screen_next(P2(gs_screen_enum *, floatp)); + + /* "Client data" interface for graphics states. */ + typedef char/*void*/ *(*gs_state_alloc_proc_t)(P1(const gs_memory_procs *mp)); + typedef int (*gs_state_copy_proc_t)(P2(char/*void*/ *to, const char/*void*/ *from)); + typedef void (*gs_state_free_proc_t)(P2(char/*void*/ *old, const gs_memory_procs *mp)); + typedef struct gs_state_client_procs_s { + gs_state_alloc_proc_t alloc; + gs_state_copy_proc_t copy; + gs_state_free_proc_t free; + } gs_state_client_procs; + void gs_state_set_client(P3(gs_state *, char/*void*/ *, const gs_state_client_procs *)); + char/*void*/ *gs_state_client_data(P1(gs_state *)); diff -rc2N gs241/gst.bat gs25/gst.bat *** gs241/gst.bat Thu Feb 27 02:31:12 1992 --- gs25/gst.bat Wed May 20 14:28:12 1992 *************** *** 1 **** ! @gs -q %1 %2 %3 %4 %5 %6 %7 %8 %9 >t \ No newline at end of file --- 1 ---- ! @gs %1 %2 %3 %4 %5 %6 %7 %8 %9 >t \ No newline at end of file diff -rc2N gs241/gstdev.c gs25/gstdev.c *** gs241/gstdev.c Fri Feb 28 14:38:20 1992 --- gs25/gstdev.c Thu Jun 18 06:59:46 1992 *************** *** 21,24 **** --- 21,25 ---- /* Device tracing for Ghostscript library */ #include "gx.h" + #include "gserrors.h" #include "gxfixed.h" /* for gxmatrix.h */ #include "gxmatrix.h" /* for gxdevice.h */ *************** *** 129,133 **** } private void ! trace_print_tile(gx_bitmap *tile) { int i; dprintf1("\t{ static byte data = { 0x%x", tile->data[0]); --- 130,134 ---- } private void ! trace_print_tile(const gx_bitmap *tile) { int i; dprintf1("\t{ static byte data = { 0x%x", tile->data[0]); *************** *** 208,212 **** } private int ! trace_tile_rectangle(gx_device *dev, gx_bitmap *tile, int x, int y, int w, int h, gx_color_index zero, gx_color_index one, int px, int py) --- 209,213 ---- } private int ! trace_tile_rectangle(gx_device *dev, const gx_bitmap *tile, int x, int y, int w, int h, gx_color_index zero, gx_color_index one, int px, int py) *************** *** 222,226 **** } private int ! trace_copy_mono(gx_device *dev, byte *data, int dx, int raster, gx_bitmap_id id, int x, int y, int w, int h, gx_color_index zero, gx_color_index one) --- 223,227 ---- } private int ! trace_copy_mono(gx_device *dev, const byte *data, int dx, int raster, gx_bitmap_id id, int x, int y, int w, int h, gx_color_index zero, gx_color_index one) *************** *** 234,238 **** } private int ! trace_copy_color(gx_device *dev, byte *data, int dx, int raster, gx_bitmap_id id, int x, int y, int w, int h) { int result = (*rprocs->copy_color)(dev, data, --- 235,239 ---- } private int ! trace_copy_color(gx_device *dev, const byte *data, int dx, int raster, gx_bitmap_id id, int x, int y, int w, int h) { int result = (*rprocs->copy_color)(dev, data, diff -rc2N gs241/gstext.icx gs25/gstext.icx *** gs241/gstext.icx --- gs25/gstext.icx Fri Jun 12 18:42:28 1992 *************** *** 0 **** --- 1,48 ---- + 0000010001002020100000000000e802 + 00001600000028000000200000004000 + 00000100040000000000800200000000 + 00000000000000000000000000000000 + 00000000800000800000008080008000 + 00008000800080800000808080004040 + 40000000ff0000ff000000ffff00ff00 + 0000ff00ff00ffff0000ffffff001111 + 11111111111111111111111111111111 + 11111111111111111111111111111111 + 1bbbb111bbb111bbb11111b111111111 + 1b111b1b111b1b111b11111111111111 + 1b111b1b111b1b111b1111b111111111 + 1b111b1b111b1b111b1111b111111111 + 1bbbb111bbb111bbb11111b111111111 + 1b11111111111111111111b111111111 + 1b11111111111111111111b111111111 + 11111111111111111111111111110000 + 00fffffffffffffffff0000000000000 + 000ffffffffffff0f000000000000000 + 0000ffffffffffff0000000000000000 + 00000ffffffffffff000000f000000ff + 000ff0fffffffffff00ffffff000000f + ffff0fffffffffff0ffffffff0000fff + fffff0fffffffffffffffffffff00000 + fffffffffffffffffffff000ff0000ff + f000fffffffffffffffff0000ff000f0 + 0000ffffffffffffffff000000000000 + 00000ffffffffffff0f0000000000000 + 0000000fff0ff00fff00000000000000 + 0000000ff0fff00fff00000000000000 + 0000000000ffffffff00000000000000 + 0000000000ffffffff00000000000000 + 0000000000ff0f0ff000000000000000 + 00000000000fffff0000000000000000 + 00000000000ffff00000000000000000 + 0000000000ffff000000000000000000 + 000000000ffff0000000000000000000 + 0000000000ff00000000000000000000 + 00000000000000000000000000000000 + 00000000000000000000000000000000 + 00000000000000000000000000000000 + 000000000000f80000fffc0001fffe00 + 07efcc00020780000003800000010000 + 0000800000018000003086000079df00 + 00ffff8001ffffc001ffffe001fffff8 + 01fffff803fffff807fffffc0ffffff8 + 1ffffff03ffffff87ffffffcffff diff -rc2N gs241/gstype1.c gs25/gstype1.c *** gs241/gstype1.c Mon Apr 6 16:11:56 1992 --- gs25/gstype1.c Mon Jul 20 15:19:06 1992 *************** *** 37,47 **** /* Define the amount of thickening to be applied to characters. */ ! #define type1_fill_adjust 0.25 /* Encrypt a string. */ int ! gs_type1_encrypt(byte *dest, byte *src, uint len, crypt_state *pstate) { register crypt_state state = *pstate; ! register byte *from = src; register byte *to = dest; register uint count = len; --- 37,49 ---- /* Define the amount of thickening to be applied to characters. */ ! /* This is a hack to avoid dropouts when there are no hints. */ ! #define adjust_with_hints 0.0 ! #define adjust_without_hints 0.2 /* Encrypt a string. */ int ! gs_type1_encrypt(byte *dest, const byte *src, uint len, crypt_state *pstate) { register crypt_state state = *pstate; ! register const byte *from = src; register byte *to = dest; register uint count = len; *************** *** 55,61 **** /* Decrypt a string. */ int ! gs_type1_decrypt(byte *dest, byte *src, uint len, crypt_state *pstate) { register crypt_state state = *pstate; ! register byte *from = src; register byte *to = dest; register uint count = len; --- 57,63 ---- /* Decrypt a string. */ int ! gs_type1_decrypt(byte *dest, const byte *src, uint len, crypt_state *pstate) { register crypt_state state = *pstate; ! register const byte *from = src; register byte *to = dest; register uint count = len; *************** *** 71,122 **** } - /* Define the structures for the state of a Type 1 interpreter. */ - /* This is the interpreter state that must be saved and restored */ - /* when calling a CharString subroutine. */ - typedef struct { - byte *ip; - crypt_state dstate; - } ip_state; - /* Define the stem hint tables. */ - /* Each stem hint table is kept sorted. */ - #define max_stems 3 /* arbitrary */ - typedef struct { - fixed v0, v1; /* coordinates (widened a little) */ - gs_fixed_point adjust_lower, adjust_upper; /* adjustments */ - } stem_hint; - typedef struct { - int count; - stem_hint *current; /* cache cursor for search */ - stem_hint data[max_stems]; - } stem_hint_table; - /* This is the full state of the Type 1 interpreter. */ - #define ostack_size 24 /* per documentation */ - #define ipstack_size 10 /* per documentation */ - struct gs_type1_state_s { - /* The following are set at initialization */ - gs_show_enum *penum; /* show enumerator */ - gs_state *pgs; /* graphics state */ - gs_type1_data *pdata; /* font-specific data */ - int charpath_flag; /* 0 for show, 1 for false */ - /* charpath, 2 for true charpath */ - int paint_type; /* 0/3 for fill, 1/2 for stroke */ - fixed_coeff fc; /* cached fixed coefficients */ - float flatness; /* flatness for character curves */ - /* The following are updated dynamically */ - fixed ostack[ostack_size]; /* the Type 1 operand stack */ - int os_count; /* # of occupied stack entries */ - ip_state ipstack[ipstack_size+1]; /* control stack */ - int ips_count; /* # of occupied entries */ - gs_fixed_point lsb; /* left side bearing */ - gs_fixed_point width; /* character width */ - int seac_base; /* base character code for seac, */ - /* or -1 */ - /* The following are set dynamically, */ - /* but not actually used yet. */ - int in_dotsection; /* true if inside dotsection */ - stem_hint_table hstem_hints; /* horizontal stem hints */ - stem_hint_table vstem_hints; /* vertical stem hints */ - }; - /* Export the size of the structure */ const uint gs_type1_state_sizeof = sizeof(gs_type1_state); --- 73,76 ---- *************** *** 140,148 **** pis->seac_base = -1; pis->in_dotsection = 0; ! pis->hstem_hints.count = 0; ! pis->hstem_hints.current = &pis->hstem_hints.data[0]; ! pis->vstem_hints.count = 0; ! pis->vstem_hints.current = &pis->vstem_hints.data[0]; gx_matrix_to_fixed_coeff(&ctm_only(pgs), &pis->fc, max_coeff_bits); /* Set the current point of the path to the origin, */ /* in anticipation of the initial [h]sbw. */ --- 94,102 ---- pis->seac_base = -1; pis->in_dotsection = 0; ! pis->vstem3_set = 0; ! pis->vs_offset.x = pis->vs_offset.y = 0; ! reset_stem_hints(pis); gx_matrix_to_fixed_coeff(&ctm_only(pgs), &pis->fc, max_coeff_bits); + compute_font_hints(&pis->fh, &pgs->ctm, pdata); /* Set the current point of the path to the origin, */ /* in anticipation of the initial [h]sbw. */ *************** *** 154,161 **** /* reasonably good-looking curves, regardless of its */ /* current value in the graphics state. */ - if ( (pis->flatness = pgs->flatness) > 1.0 ) { /* With the conventional 1000-unit characters, */ /* a small "o" will be about 250 units, */ /* so set the flatness to 10 units. */ float cxx = pgs->ctm.xx, cyy = pgs->ctm.yy; if ( cxx < 0 ) cxx = -cxx; --- 108,116 ---- /* reasonably good-looking curves, regardless of its */ /* current value in the graphics state. */ { /* With the conventional 1000-unit characters, */ /* a small "o" will be about 250 units, */ /* so set the flatness to 10 units. */ + /* If the character is very small, set the flatness */ + /* to zero, which will produce very accurate curves. */ float cxx = pgs->ctm.xx, cyy = pgs->ctm.yy; if ( cxx < 0 ) cxx = -cxx; *************** *** 169,173 **** if ( cyx > cxx ) cxx = cyx; } ! pis->flatness = (cxx > 0.1 ? cxx * 10 : 1.0); } return 0; --- 124,130 ---- if ( cyx > cxx ) cxx = cyx; } ! /* Now cxx is approximately one character space unit */ ! /* in device pixels. */ ! pis->flatness = (cxx > 0.1 ? cxx * 10 : 0.0); } return 0; *************** *** 178,182 **** # define dc(str) if ( gs_debug['1'] ) type1_trace(cip, c, str); private void near ! type1_trace(byte *cip, byte c, char _ds *str) { dprintf3("[1]%lx: %02x %s\n", (ulong)(cip - 1), c, (char *)str); } --- 135,139 ---- # define dc(str) if ( gs_debug['1'] ) type1_trace(cip, c, str); private void near ! type1_trace(const byte *cip, byte c, const char _ds *str) { dprintf3("[1]%lx: %02x %s\n", (ulong)(cip - 1), c, (char *)str); } *************** *** 221,229 **** /* We round all endpoints of lines or curves */ ! /* to the center of the nearest quarter-pixel, and suppress null lines. */ /* (Rounding to the half-pixel causes too many dropouts.) */ /* This saves a lot of rendering work for small characters. */ #define pixel_rounded(fx)\ ! (((fx) | float2fixed(0.125)) & float2fixed(-0.125)) #define must_draw_to(lpx, lpy, px, py)\ ((lpx = pixel_rounded(px)), (lpy = pixel_rounded(py)),\ --- 178,186 ---- /* We round all endpoints of lines or curves */ ! /* to the nearest quarter-pixel, and suppress null lines. */ /* (Rounding to the half-pixel causes too many dropouts.) */ /* This saves a lot of rendering work for small characters. */ #define pixel_rounded(fx)\ ! (((fx) + float2fixed(0.125)) & float2fixed(-0.25)) #define must_draw_to(lpx, lpy, px, py)\ ((lpx = pixel_rounded(px)), (lpy = pixel_rounded(py)),\ *************** *** 257,266 **** else pis->width.x = wx, pis->width.y = wy; ! #ifdef DEBUG ! if ( gs_debug['1'] ) ! dprintf4("[1]sb=(%g,%g) w=(%g,%g)\n", ! fixed2float(pis->lsb.x), fixed2float(pis->lsb.y), ! fixed2float(pis->width.x), fixed2float(pis->width.y)); ! #endif accum_xy(pis->lsb.x, pis->lsb.y); return 0; --- 214,220 ---- else pis->width.x = wx, pis->width.y = wy; ! if_debug4('1',"[1]sb=(%g,%g) w=(%g,%g)\n", ! fixed2float(pis->lsb.x), fixed2float(pis->lsb.y), ! fixed2float(pis->width.x), fixed2float(pis->width.y)); accum_xy(pis->lsb.x, pis->lsb.y); return 0; *************** *** 275,279 **** gs_op1_rrcurveto(register is_ptr ps, fixed dx1, fixed dy1, fixed dx2, fixed dy2, fixed dx3, fixed dy3) ! { fixed ptx1, pty1, ptx2, pty2; /* Following declarations are only for must_draw_to */ fixed lpx, lpy; --- 229,236 ---- gs_op1_rrcurveto(register is_ptr ps, fixed dx1, fixed dy1, fixed dx2, fixed dy2, fixed dx3, fixed dy3) ! { gs_fixed_point pt1, pt2, pt3; ! gs_type1_state *pis = ps->pis; ! fixed ax0 = pixel_rounded(ptx) - ptx; ! fixed ay0 = pixel_rounded(pty) - pty; /* Following declarations are only for must_draw_to */ fixed lpx, lpy; *************** *** 281,290 **** segment *pseg; accum_xy(dx1, dy1); ! ptx1 = ptx, pty1 = pty; accum_xy(dx2, dy2); ! ptx2 = ptx, pty2 = pty; accum_xy(dx3, dy3); ! if ( must_draw_to(lpx, lpy, ptx, pty) ) ! return gx_path_add_flattened_curve(sppath, ptx1, pty1, ptx2, pty2, lpx, lpy, ps->pis->flatness); return 0; } --- 238,252 ---- segment *pseg; accum_xy(dx1, dy1); ! pt1.x = ptx + ax0, pt1.y = pty + ay0; accum_xy(dx2, dy2); ! pt2.x = ptx, pt2.y = pty; accum_xy(dx3, dy3); ! find_stem_hints(pis, ptx, pty, dx3, dy3, &pt3); ! if ( must_draw_to(lpx, lpy, pt3.x, pt3.y) ) ! { /* Adjust second control point for endpoint hint */ ! /* and rounding. */ ! pt2.x += lpx - ptx, pt2.y += lpy - pty; ! return gx_path_add_flattened_curve(sppath, pt1.x, pt1.y, pt2.x, pt2.y, lpx, lpy, pis->flatness); ! } return 0; } *************** *** 300,309 **** /* The int * argument is where the character is stored for seac, */ /* or the othersubr # for callothersubr. */ - private void near type1_hstem(P3(gs_type1_state *, fixed, fixed)); - private void near type1_vstem(P3(gs_type1_state *, fixed, fixed)); - private stem_hint *near type1_stem(P3(stem_hint_table *, fixed, fixed)); private int near type1_endchar(P3(gs_type1_state *, gs_state *, gx_path *)); int ! gs_type1_interpret(register gs_type1_state *pis, byte *str, int *pindex) { gs_state *pgs = pis->pgs; gs_type1_data *pdata = pis->pdata; --- 262,268 ---- /* The int * argument is where the character is stored for seac, */ /* or the othersubr # for callothersubr. */ private int near type1_endchar(P3(gs_type1_state *, gs_state *, gx_path *)); int ! gs_type1_interpret(register gs_type1_state *pis, const byte *str, int *pindex) { gs_state *pgs = pis->pgs; gs_type1_data *pdata = pis->pdata; *************** *** 325,329 **** #define clear csp = cstack - 1 ip_state *ipsp = &pis->ipstack[pis->ips_count - 1]; ! register byte *cip; register crypt_state state; register int c; --- 284,288 ---- #define clear csp = cstack - 1 ip_state *ipsp = &pis->ipstack[pis->ips_count - 1]; ! register const byte *cip; register crypt_state state; register int c; *************** *** 330,333 **** --- 289,294 ---- int code = 0; fixed ftx = pgs->ctm.tx_fixed, fty = pgs->ctm.ty_fixed; + gs_fixed_point hpt; + /* Following are only for must_draw_to */ fixed lpx, lpy; subpath *psub; *************** *** 375,381 **** cnext; case c_vmoveto: dc("vmoveto") ! accum_y(cs0); ! move: /* Round to the nearest center of a quarter-pixel. */ ! if ( must_draw_to(lpx, lpy, ptx, pty) ) code = gx_path_add_point(sppath, lpx, lpy); goto cc; --- 336,346 ---- cnext; case c_vmoveto: dc("vmoveto") ! cs1 = cs0; ! cs0 = 0; ! accum_y(cs1); ! move: /* cs0 = dx, cs1 = dy for hint checking. */ ! find_stem_hints(pis, ptx, pty, cs0, cs1, &hpt); ! /* Round to the nearest center of a quarter-pixel. */ ! if ( must_draw_to(lpx, lpy, hpt.x, hpt.y) ) code = gx_path_add_point(sppath, lpx, lpy); goto cc; *************** *** 382,401 **** case c_rlineto: dc("rlineto") accum_xy(cs0, cs1); ! line: /* Round to the nearest center of a quarter-pixel. */ ! if ( must_draw_to(lpx, lpy, ptx, pty) ) code = gx_path_add_line(sppath, lpx, lpy); cc: if ( code < 0 ) return code; ! pp: ! #ifdef DEBUG ! if ( gs_debug['1'] ) ! dprintf2("[1]pt=(%g,%g)\n", ! fixed2float(ptx), fixed2float(pty)); ! #endif cnext; case c_hlineto: dc("hlineto") accum_x(cs0); goto line; case c_vlineto: dc("vlineto") ! accum_y(cs0); goto line; case c_rrcurveto: dc("rrcurveto") --- 347,367 ---- case c_rlineto: dc("rlineto") accum_xy(cs0, cs1); ! line: /* cs0 = dx, cs1 = dy for hint checking. */ ! find_stem_hints(pis, ptx, pty, cs0, cs1, &hpt); ! /* Round to the nearest center of a quarter-pixel. */ ! if ( must_draw_to(lpx, lpy, hpt.x, hpt.y) ) code = gx_path_add_line(sppath, lpx, lpy); cc: if ( code < 0 ) return code; ! pp: if_debug2('1', "[1]pt=(%g,%g)\n", ! fixed2float(ptx), fixed2float(pty)); cnext; case c_hlineto: dc("hlineto") accum_x(cs0); + cs1 = 0; goto line; case c_vlineto: dc("vlineto") ! cs1 = cs0; ! cs0 = 0; ! accum_y(cs1); goto line; case c_rrcurveto: dc("rrcurveto") *************** *** 407,411 **** case c_callsubr: dc("callsubr") { int index = fixed2int_var(*csp); ! byte *nip; code = (*pdata->subr_proc)(pdata, index, &nip); if ( code < 0 ) return_error(code); --- 373,377 ---- case c_callsubr: dc("callsubr") { int index = fixed2int_var(*csp); ! const byte *nip; code = (*pdata->subr_proc)(pdata, index, &nip); if ( code < 0 ) return_error(code); *************** *** 529,532 **** --- 495,499 ---- case c_hmoveto: dc("hmoveto") accum_x(cs0); + cs1 = 0; goto move; case c_vhcurveto: dc("vhcurveto") *************** *** 562,575 **** icase(245) icase(246) pi: *++csp = int2fixed(c_value_num1(c)); ! pushed: ! #ifdef DEBUG ! if ( gs_debug['1'] ) ! dprintf3("[1]%d: (%d) %f\n", ! (int)(csp - cstack), c, fixed2float(*csp)); ! #endif break; /* Handle 2-byte positive numbers. */ #define case_num2(n)\ ! case c_num2+n: *++csp = int2fixed(c_value_num2(c_num2+n, 0)) case_num2(0); goto pos2; case_num2(1); goto pos2; --- 529,538 ---- icase(245) icase(246) pi: *++csp = int2fixed(c_value_num1(c)); ! pushed: if_debug3('1', "[1]%d: (%d) %f\n", ! (int)(csp - cstack), c, fixed2float(*csp)); break; /* Handle 2-byte positive numbers. */ #define case_num2(n)\ ! case c_num2+n: c = c_value_num2(c_num2+n, 0) case_num2(0); goto pos2; case_num2(1); goto pos2; *************** *** 578,582 **** #undef case_num2 pos2: { c0 = *cip++; ! *csp += int2fixed(decrypt_this(c0, state)); decrypt_skip_next(c0, state); } goto pushed; --- 541,547 ---- #undef case_num2 pos2: { c0 = *cip++; ! if_debug2('1', "[1] (%d)+%d\n", ! c, decrypt_this(c0, state)); ! *++csp = int2fixed((int)decrypt_this(c0, state) + c); decrypt_skip_next(c0, state); } goto pushed; *************** *** 583,587 **** /* Handle 2-byte negative numbers. */ #define case_num3(n)\ ! case c_num3+n: *++csp = int2fixed(c_value_num3(c_num3+n, 0)) case_num3(0); goto neg2; case_num3(1); goto neg2; --- 548,552 ---- /* Handle 2-byte negative numbers. */ #define case_num3(n)\ ! case c_num3+n: c = c_value_num3(c_num3+n, 0) case_num3(0); goto neg2; case_num3(1); goto neg2; *************** *** 590,594 **** #undef case_num3 neg2: { c0 = *cip++; ! *csp -= int2fixed(decrypt_this(c0, state)); decrypt_skip_next(c0, state); } goto pushed; --- 555,561 ---- #undef case_num3 neg2: { c0 = *cip++; ! if_debug2('1', "[1] (%d)-%d\n", ! c, decrypt_this(c0, state)); ! *++csp = int2fixed(c - (int)decrypt_this(c0, state)); decrypt_skip_next(c0, state); } goto pushed; *************** *** 613,651 **** } ! /* Add a horizontal stem hint. */ ! private void near ! type1_hstem(gs_type1_state *pis, fixed y, fixed dy) ! { stem_hint *psh; ! if ( dy < 0 ) y += dy, dy = -dy; ! psh = type1_stem(&pis->hstem_hints, y, dy); ! if ( psh == 0 ) return; ! /* Compute adjustments here */ } ! /* Add a vertical stem hint. */ ! private void near ! type1_vstem(gs_type1_state *pis, fixed x, fixed dx) ! { stem_hint *psh; ! if ( dx < 0 ) x += dx, dx = -dx; ! psh = type1_stem(&pis->vstem_hints, x, dx); ! if ( psh == 0 ) return; ! /* Compute adjustments here */ ! } ! ! /* Add a stem hint, keeping the table sorted. */ ! /* Return the stem hint pointer, or 0 if the table is full. */ ! private stem_hint *near ! type1_stem(stem_hint_table *psht, fixed v0, fixed d) ! { stem_hint *bot = &psht->data[0]; ! stem_hint *top = bot + psht->count; ! if ( psht->count >= max_stems ) return 0; ! while ( top > bot && v0 < top[-1].v0 ) ! { *top = top[-1]; ! top--; ! } ! top->v0 = v0, top->v1 = v0 + d; ! psht->count++; ! return top; ! } /* Handle the end of a character. We break this out into a separate */ --- 580,592 ---- } ! /* Pop a (fixed) number off the internal stack. */ ! /* The client uses this to get the arguments for an OtherSubr. */ ! int ! gs_type1_pop(gs_type1_state *pis, fixed *pf) ! { *pf = pis->ostack[--(pis->os_count)]; ! return 0; } ! /* ------ Termination ------ */ /* Handle the end of a character. We break this out into a separate */ *************** *** 673,681 **** { bbox.p.x = bbox.p.y = bbox.q.x = bbox.q.y = 0; } ! #ifdef DEBUG ! if ( gs_debug['1'] ) ! dprintf4("[1]bbox=(%g,%g),(%g,%g)\n", ! bbox.p.x, bbox.p.y, bbox.q.x, bbox.q.y); ! #endif { /* Expand the bounding box to encompass */ /* the width of the stroke (if stroking). */ --- 614,619 ---- { bbox.p.x = bbox.p.y = bbox.q.x = bbox.q.y = 0; } ! if_debug4('1', "[1]bbox=(%g,%g),(%g,%g)\n", ! bbox.p.x, bbox.p.y, bbox.q.x, bbox.q.y); { /* Expand the bounding box to encompass */ /* the width of the stroke (if stroking). */ *************** *** 701,722 **** /* We've already constructed the path: */ /* translate it so it matches the cache device. */ ! gx_path_translate(pgs->path, pgs->ctm.tx_fixed - ftx, ! pgs->ctm.ty_fixed - fty); if ( code < 0 ) return code; - /****** - ****** The adjust parameter is a hack to make - ****** characters come out more bold, since we - ****** don't look at the hints. - ******/ gx_color_load(pgs->dev_color, pgs); return (use_stroke ? gs_stroke(pgs) : ! gs_fill_adjust(pgs, float2fixed(type1_fill_adjust))); ! } ! ! /* Pop a (fixed) number off the internal stack. */ ! /* The client uses this to get the arguments for an OtherSubr. */ ! int ! gs_type1_pop(gs_type1_state *pis, fixed *pf) ! { *pf = pis->ostack[--(pis->os_count)]; ! return 0; } --- 639,650 ---- /* We've already constructed the path: */ /* translate it so it matches the cache device. */ ! code = gx_path_translate(pgs->path, pgs->ctm.tx_fixed - ftx, ! pgs->ctm.ty_fixed - fty); if ( code < 0 ) return code; gx_color_load(pgs->dev_color, pgs); return (use_stroke ? gs_stroke(pgs) : ! gs_fill_adjust(pgs, ! (pis->fh.use_x_hints | pis->fh.use_y_hints ? ! float2fixed(adjust_with_hints) : ! float2fixed(adjust_without_hints)))); } diff -rc2N gs241/gstype1.h gs25/gstype1.h *** gs241/gstype1.h Sat Mar 21 02:29:26 1992 --- gs25/gstype1.h Sun May 10 18:20:24 1992 *************** *** 1,3 **** ! /* Copyright (C) 1990, 1991 Aladdin Enterprises. All rights reserved. Distributed by Free Software Foundation, Inc. --- 1,3 ---- ! /* Copyright (C) 1990, 1992 Aladdin Enterprises. All rights reserved. Distributed by Free Software Foundation, Inc. *************** *** 21,31 **** /* Client interface to Adobe Type 1 font routines for Ghostscript library */ ! /* Encrypt/decrypt procedures */ ! typedef ushort crypt_state; ! #define crypt_charstring_seed 4330 ! int gs_type1_encrypt(P4(byte *dest, byte *src, uint len, crypt_state *pstate)); ! int gs_type1_decrypt(P4(byte *dest, byte *src, uint len, crypt_state *pstate)); ! /* CharString interpreter */ typedef struct gs_type1_state_s gs_type1_state; extern const uint gs_type1_state_sizeof; --- 21,27 ---- /* Client interface to Adobe Type 1 font routines for Ghostscript library */ ! /* ------ Normal client interface ------ */ ! #define crypt_charstring_seed 4330 typedef struct gs_type1_state_s gs_type1_state; extern const uint gs_type1_state_sizeof; *************** *** 47,51 **** #define type1_result_seac 1 #define type1_result_callothersubr 2 ! int gs_type1_interpret(P3(gs_type1_state *, byte *, int *)); /* Pop a (fixed) number off the internal stack */ int gs_type1_pop(P2(gs_type1_state *, fixed *)); --- 43,112 ---- #define type1_result_seac 1 #define type1_result_callothersubr 2 ! int gs_type1_interpret(P3(gs_type1_state *, const byte *, int *)); /* Pop a (fixed) number off the internal stack */ int gs_type1_pop(P2(gs_type1_state *, fixed *)); + + /* ------ CharString representation ------ */ + + /* Define the charstring command set */ + typedef enum { + c_undef0 = 0, + c_hstem = 1, + c_undef2 = 2, + c_vstem = 3, + c_vmoveto = 4, + c_rlineto = 5, + c_hlineto = 6, + c_vlineto = 7, + c_rrcurveto = 8, + c_closepath = 9, + c_callsubr = 10, + c_return = 11, + c_escape = 12, /* extends the command set */ + c_hsbw = 13, + c_endchar = 14, + c_undoc15 = 15, /* Undocumented by Adobe, */ + /* but used in some Adobe fonts. */ + c_undef16 = 16, + c_undef17 = 17, + c_undef18 = 18, + c_undef19 = 19, + c_undef20 = 20, + c_rmoveto = 21, + c_hmoveto = 22, + c_undef23 = 23, + c_undef24 = 24, + c_undef25 = 25, + c_undef26 = 26, + c_undef27 = 27, + c_undef28 = 28, + c_undef29 = 29, + c_vhcurveto = 30, + c_hvcurveto = 31 + } char_command; + typedef enum { /* extended commands */ + ce_dotsection = 0, + ce_vstem3 = 1, + ce_hstem3 = 2, + ce_seac = 6, + ce_sbw = 7, + ce_div = 12, + ce_undoc15 = 15, /* Undocumented by Adobe, */ + /* but used in some Adobe fonts. */ + ce_callothersubr = 16, + ce_pop = 17, + ce_setcurrentpoint = 33 + } char_extended_command; + + /* Define the encoding of numbers */ + #define c_num1 32 + #define c_value_num1(ch) ((int)(byte)(ch) - 139) + #define c_num2 247 + #define c_value_num2(c1,c2)\ + (((int)(byte)((c1) - c_num2) << 8) + (int)(byte)(c2) + 108) + #define c_num3 251 + #define c_value_num3(c1,c2)\ + -(((int)(byte)((c1) - c_num3) << 8) + (int)(byte)(c2) + 108) + /* Otherwise, the first byte is 255, followed by a 32-bit 2's complement */ + /* number in big-endian order. */ + #define c_num4 255 diff -rc2N gs241/gsw.tr gs25/gsw.tr *** gs241/gsw.tr Sun Apr 12 15:05:28 1992 --- gs25/gsw.tr Thu Aug 13 18:42:14 1992 *************** *** 2,6 **** OPTION MAP=gs FILE gs,gsmain ! FILE ialloc,idebug,idict,iinit,iname FILE interp,isave,iscan,iutil,sfilter,stream FILE zarith,zarray,zcontrol,zdict --- 2,6 ---- OPTION MAP=gs FILE gs,gsmain ! FILE ialloc,idebug,idict,idparam,iinit,iname FILE interp,isave,iscan,iutil,sfilter,stream FILE zarith,zarray,zcontrol,zdict *************** *** 10,16 **** FILE zht,zmatrix,zpaint,zpath,zpath2 FILE gschar,gscolor,gscoord,gsdevice,gsfile ! FILE gsfont,gsimage,gsim2out,gsline,gsmatrix,gsmisc FILE gspaint,gspath,gspath2,gsstate,gstdev,gstype1,gsutil FILE gxcache,gxclist,gxcolor,gxcpath,gxdither,gxdraw,gxfill ! FILE gxht,gxpath,gxpath2,gxstroke FILE gdevmem1,gdevmem2,gdevmem3,gconfig --- 10,16 ---- FILE zht,zmatrix,zpaint,zpath,zpath2 FILE gschar,gscolor,gscoord,gsdevice,gsfile ! FILE gsfont,gsimage,gsimage2,gsimpath,gsline,gsmatrix,gsmisc FILE gspaint,gspath,gspath2,gsstate,gstdev,gstype1,gsutil FILE gxcache,gxclist,gxcolor,gxcpath,gxdither,gxdraw,gxfill ! FILE gxhint1,gxht,gxpath,gxpath2,gxpcopy,gxstroke FILE gdevmem1,gdevmem2,gdevmem3,gconfig diff -rc2N gs241/gx.h gs25/gx.h *** gs241/gx.h Fri Apr 17 16:17:36 1992 --- gs25/gx.h Sat May 9 17:44:50 1992 *************** *** 21,55 **** /* Common internal definitions for Ghostscript library */ #include "gs.h" ! ! /* Debugging options array */ ! extern char gs_debug[128]; ! ! /* Debugging printout macros. */ ! #ifdef DEBUG ! # define if_d_c(c)\ ! if(c>='a' && c<='z' ? gs_debug[c] | gs_debug[c^32] : gs_debug[c]) ! # define if_debug0(c,s)\ ! if_d_c(c) dprintf(s) ! # define if_debug1(c,s,a1)\ ! if_d_c(c) dprintf1(s,a1) ! # define if_debug2(c,s,a1,a2)\ ! if_d_c(c) dprintf2(s,a1,a2) ! # define if_debug3(c,s,a1,a2,a3)\ ! if_d_c(c) dprintf3(s,a1,a2,a3) ! # define if_debug4(c,s,a1,a2,a3,a4)\ ! if_d_c(c) dprintf4(s,a1,a2,a3,a4) ! # define if_debug5(c,s,a1,a2,a3,a4,a5)\ ! if_d_c(c) dprintf5(s,a1,a2,a3,a4,a5) ! # define if_debug6(c,s,a1,a2,a3,a4,a5,a6)\ ! if_d_c(c) dprintf6(s,a1,a2,a3,a4,a5,a6) ! #else ! # define if_debug0(c,s) 0 ! # define if_debug1(c,s,a1) 0 ! # define if_debug2(c,s,a1,a2) 0 ! # define if_debug3(c,s,a1,a2,a3) 0 ! # define if_debug4(c,s,a1,a2,a3,a4) 0 ! # define if_debug5(c,s,a1,a2,a3,a4,a5) 0 ! # define if_debug6(c,s,a1,a2,a3,a4,a5,a6) 0 ! #endif /* Error return macro */ --- 21,25 ---- /* Common internal definitions for Ghostscript library */ #include "gs.h" ! #include "gdebug.h" /* Error return macro */ diff -rc2N gs241/gxarith.h gs25/gxarith.h *** gs241/gxarith.h Tue Jun 18 13:38:12 1991 --- gs25/gxarith.h Mon Apr 27 03:06:40 1992 *************** *** 37,41 **** /* Test floating point values against zero. */ ! #ifdef vax /* not IEEE format! */ # define is_fzero(f) ((f) == 0) # define is_fzero2(f1,f2) ((f1) == 0 && (f2) == 0) --- 37,41 ---- /* Test floating point values against zero. */ ! #if !arch_floats_are_IEEE /* e.g., VAX */ # define is_fzero(f) ((f) == 0) # define is_fzero2(f1,f2) ((f1) == 0 && (f2) == 0) diff -rc2N gs241/gxbitmap.h gs25/gxbitmap.h *** gs241/gxbitmap.h Thu Jan 9 15:50:30 1992 --- gs25/gxbitmap.h Wed Jun 3 19:06:00 1992 *************** *** 39,43 **** * do word-oriented operations on them if you're on a little-endian * platform like the Intel 80x86 or VAX). Each scan line must start on ! * a (32-bit) word boundary, and hence must be is padded to a word boundary, * although this should rarely be of concern, since the raster and width * are specified individually. The first scan line corresponds to y=0 --- 39,43 ---- * do word-oriented operations on them if you're on a little-endian * platform like the Intel 80x86 or VAX). Each scan line must start on ! * a (32-bit) word boundary, and hence is padded to a word boundary, * although this should rarely be of concern, since the raster and width * are specified individually. The first scan line corresponds to y=0 diff -rc2N gs241/gxcache.c gs25/gxcache.c *** gs241/gxcache.c Sat Apr 18 02:21:50 1992 --- gs25/gxcache.c Sun Jul 12 20:09:24 1992 *************** *** 22,25 **** --- 22,26 ---- #include "gx.h" #include "memory_.h" + #include "gpcheck.h" #include "gserrors.h" #include "gxfixed.h" *************** *** 80,84 **** gx_alloc_char_bits(gs_font_dir *dir, gx_device_memory *dev, ushort iwidth, ushort iheight) ! { ulong isize, cdsize; cached_char_head *cch; #define hcc ((cached_char *)cch) --- 81,87 ---- gx_alloc_char_bits(gs_font_dir *dir, gx_device_memory *dev, ushort iwidth, ushort iheight) ! { ulong isize, icdsize; ! uint iraster; ! uint cdsize; cached_char_head *cch; #define hcc ((cached_char *)cch) *************** *** 88,97 **** dev->width = iwidth; dev->height = iheight; ! isize = gdev_mem_bitmap_size(dev); /* sets raster */ ! if ( dev->raster != 0 && iheight > dir->upper / dev->raster ) return 0; /* too big */ ! cdsize = isize + cached_char_sizeof; ! if ( cdsize >= dir->cmax ) return 0; /* too big */ /* Look for and/or free enough space. */ cch = (cached_char_head *)(dir->cdata + dir->cnext); --- 91,102 ---- dev->width = iwidth; dev->height = iheight; ! iraster = gdev_mem_raster(dev); ! if ( iraster != 0 && iheight > dir->upper / iraster ) return 0; /* too big */ ! isize = gdev_mem_bitmap_size(dev); ! icdsize = isize + cached_char_sizeof; ! if ( icdsize > dir->cdata_size ) return 0; /* too big */ + cdsize = (uint)icdsize; /* Look for and/or free enough space. */ cch = (cached_char_head *)(dir->cdata + dir->cnext); *************** *** 122,129 **** { shorten_cached_char(dir, cc, fsize - cdsize); if_debug2('K', "[K]shortening 0x%lx by %u (initial)\n", ! (ulong)cc, (uint)(fsize - cdsize)); } if_debug4('k', "[k]adding 0x%lx:%u(%u,%u)\n", ! (ulong)cc, (uint)cdsize, iwidth, iheight); bits = cc_bits(cc); memset((char *)bits, 0, (uint)isize); --- 127,134 ---- { shorten_cached_char(dir, cc, fsize - cdsize); if_debug2('K', "[K]shortening 0x%lx by %u (initial)\n", ! (ulong)cc, fsize - cdsize); } if_debug4('k', "[k]adding 0x%lx:%u(%u,%u)\n", ! (ulong)cc, cdsize, iwidth, iheight); bits = cc_bits(cc); memset((char *)bits, 0, (uint)isize); *************** *** 130,134 **** cc->width = iwidth; cc->height = iheight; ! cc->raster = dev->raster; cc->head.pair = 0; /* not linked in yet */ dev->base = bits; --- 135,139 ---- cc->width = iwidth; cc->height = iheight; ! cc->raster = iraster; cc->head.pair = 0; /* not linked in yet */ dev->base = bits; *************** *** 157,161 **** /* Look up, and if necessary add, a font/matrix pair in the cache */ cached_fm_pair * ! gx_lookup_fm_pair(register gs_state *pgs) { float mxx = pgs->char_tm.xx, mxy = pgs->char_tm.xy, myx = pgs->char_tm.yx, myy = pgs->char_tm.yy; --- 162,166 ---- /* Look up, and if necessary add, a font/matrix pair in the cache */ cached_fm_pair * ! gx_lookup_fm_pair(register const gs_state *pgs) { float mxx = pgs->char_tm.xx, mxy = pgs->char_tm.xy, myx = pgs->char_tm.yx, myy = pgs->char_tm.yy; *************** *** 234,238 **** /* Return the cached_char or 0. */ cached_char * ! gx_lookup_cached_char(gs_state *pgs, cached_fm_pair *pair, char_code ccode) { gs_font_dir *dir = pgs->font->dir; register cached_char *cc = *chars_head(dir, ccode, pair); --- 239,243 ---- /* Return the cached_char or 0. */ cached_char * ! gx_lookup_cached_char(const gs_state *pgs, const cached_fm_pair *pair, char_code ccode) { gs_font_dir *dir = pgs->font->dir; register cached_char *cc = *chars_head(dir, ccode, pair); *************** *** 251,255 **** /* occurred, or a negative error code. */ int ! gx_image_cached_char(register gs_show_enum *penum, register cached_char *cc) { register gs_state *pgs = penum->pgs; int x, y, w, h; --- 256,260 ---- /* occurred, or a negative error code. */ int ! gx_image_cached_char(register gs_show_enum *penum, register const cached_char *cc) { register gs_state *pgs = penum->pgs; int x, y, w, h; *************** *** 276,284 **** h = cc->height; #ifdef DEBUG ! if ( gs_debug['K'] ) ! dprintf3("[K]copying 0x%lx, offset=(%g,%g)\n", (ulong)cc, ! fixed2float(-cc->offset.x), fixed2float(-cc->offset.y)), ! dprintf6(" at (%g,%g)+(%d,%d)->(%d,%d)\n", fixed2float(pt.x), ! fixed2float(pt.y), penum->ftx, penum->fty, x, y); #endif if ( x < penum->cxmin || x + w > penum->cxmax || --- 281,294 ---- h = cc->height; #ifdef DEBUG ! if ( gs_debug['K'] ) ! { debug_dump_bytes(cc_bits(cc), cc_bits(cc) + cc->raster * h, ! "[K]bits"); ! dprintf3("[K]copying 0x%lx, offset=(%g,%g)\n", (ulong)cc, ! fixed2float(-cc->offset.x), ! fixed2float(-cc->offset.y)); ! dprintf6(" at (%g,%g)+(%d,%d)->(%d,%d)\n", ! fixed2float(pt.x), fixed2float(pt.y), ! penum->ftx, penum->fty, x, y); ! } #endif if ( x < penum->cxmin || x + w > penum->cxmax || *************** *** 297,300 **** --- 307,311 ---- x, y, w, h, gx_no_color_index, pgs->dev_color->color1); + gp_check_interrupts(); return ( code < 0 ? code : 0 ); } *************** *** 302,306 **** /* Purge from the caches all references to a given font. */ void ! gs_purge_font_from_char_caches(gs_font_dir *dir, gs_font *font) { cached_fm_pair *pair = dir->mdata; int count = dir->mmax; --- 313,317 ---- /* Purge from the caches all references to a given font. */ void ! gs_purge_font_from_char_caches(gs_font_dir *dir, const gs_font *font) { cached_fm_pair *pair = dir->mdata; int count = dir->mmax; diff -rc2N gs241/gxchar.h gs25/gxchar.h *** gs241/gxchar.h Sat Mar 21 02:27:28 1992 --- gs25/gxchar.h Mon Jul 20 17:23:20 1992 *************** *** 29,33 **** struct gs_font_s *font; /* base font */ long UniqueID; /* font UniqueID */ ! char * /* void * */ encoding; /* encoding vector (opaque) */ float mxx, mxy, myx, myy; /* transformation */ int num_chars; /* # of cached chars with this */ --- 29,33 ---- struct gs_font_s *font; /* base font */ long UniqueID; /* font UniqueID */ ! const char * /* void * */ encoding; /* encoding vector (opaque) */ float mxx, mxy, myx, myy; /* transformation */ int num_chars; /* # of cached chars with this */ *************** *** 52,56 **** gs_state *pgs; int level; /* save the level of pgs */ ! byte *str; /* char may be signed! */ uint size; float wcx, wcy; /* for widthshow */ --- 52,56 ---- gs_state *pgs; int level; /* save the level of pgs */ ! const byte *str; /* char may be signed! */ uint size; float wcx, wcy; /* for widthshow */ *************** *** 105,111 **** void gx_free_cached_char(P2(gs_font_dir *, cached_char *)); cached_fm_pair * ! gx_lookup_fm_pair(P1(gs_state *)); void gx_add_cached_char(P4(gs_font_dir *, gx_device_memory *, cached_char *, cached_fm_pair *)); cached_char * ! gx_lookup_cached_char(P3(gs_state *, cached_fm_pair *, char_code)); ! int gx_image_cached_char(P2(gs_show_enum *, cached_char *)); --- 105,111 ---- void gx_free_cached_char(P2(gs_font_dir *, cached_char *)); cached_fm_pair * ! gx_lookup_fm_pair(P1(const gs_state *)); void gx_add_cached_char(P4(gs_font_dir *, gx_device_memory *, cached_char *, cached_fm_pair *)); cached_char * ! gx_lookup_cached_char(P3(const gs_state *, const cached_fm_pair *, char_code)); ! int gx_image_cached_char(P2(gs_show_enum *, const cached_char *)); diff -rc2N gs241/gxclist.c gs25/gxclist.c *** gs241/gxclist.c Thu Apr 16 18:06:32 1992 --- gs25/gxclist.c Fri Aug 14 05:49:38 1992 *************** *** 129,134 **** count_op(int op) { ++cmd_op_counts[op]; ! if ( gs_debug['L'] ) ! dprintf2(", %s %d\n", cmd_op_names[op >> 4], op & 0xf), fflush(dstderr); return op; --- 129,133 ---- count_op(int op) { ++cmd_op_counts[op]; ! if_debug2('L', ", %s %d\n", cmd_op_names[op >> 4], op & 0xf), fflush(dstderr); return op; *************** *** 202,205 **** --- 201,209 ---- * and for the rendering buffer (image device) when reading. * For the moment, we divide the space up arbitrarily. + * + * This routine requires only data, data_size, target, and mdev + * to have been set in the device structure, and is idempotent, + * so it can be used to check whether a given-size buffer + * is large enough. */ byte *data = cdev->data; *************** *** 214,229 **** cdev->tile_data_size = (size / 5) & -4; /* arbitrary! */ alloc_data(cdev->tile_data_size); ! raster = (((target->width * target->color_info.depth + 31) >> 5) << 2) + sizeof(byte *); cdev->band_height = size / (uint)raster; nbands = target->height / cdev->band_height + 1; cdev->nbands = nbands; ! #ifdef DEBUG ! if ( gs_debug['l'] | gs_debug['L'] ) ! dprintf4("[l]width=%d, raster=%d, band_height=%d, nbands=%d\n", target->width, raster, cdev->band_height, cdev->nbands); - #endif state_size = nbands * sizeof(gx_clist_state); ! if ( state_size > size / 2 ) ! return -1; /* not enough room */ cdev->mdev.base = data; cdev->states = states = (gx_clist_state *)data; --- 218,232 ---- cdev->tile_data_size = (size / 5) & -4; /* arbitrary! */ alloc_data(cdev->tile_data_size); ! raster = ((((ulong)(target->width) * target->color_info.depth + 31) >> 5) << 2) + sizeof(byte *); cdev->band_height = size / (uint)raster; + if ( cdev->band_height == 0 ) /* can't even fit one scan line */ + return_error(gs_error_limitcheck); nbands = target->height / cdev->band_height + 1; cdev->nbands = nbands; ! if_debug4('l', "[l]width=%d, raster=%d, band_height=%d, nbands=%d\n", target->width, raster, cdev->band_height, cdev->nbands); state_size = nbands * sizeof(gx_clist_state); ! if ( state_size > size - (sizeof(cmd_prefix) + cmd_largest_size + raster + 4) ) /* not enough room */ ! return_error(gs_error_limitcheck); cdev->mdev.base = data; cdev->states = states = (gx_clist_state *)data; *************** *** 264,273 **** cldev->tile_hash_mask = hc; hc++; /* make actual size */ ! #ifdef DEBUG ! if ( gs_debug['l'] | gs_debug['L'] ) ! dprintf5("[l]tile.size=%dx%d, slot_size=%d, max_count=%d, hc=%d\n", cldev->tile.size.x, cldev->tile.size.y, cldev->tile_slot_size, cldev->tile_max_count, hc); - #endif cldev->tile_hash_table = (tile_hash *)(cldev->tile_data + cldev->tile_data_size) - hc; --- 267,273 ---- cldev->tile_hash_mask = hc; hc++; /* make actual size */ ! if_debug5('l', "[l]tile.size=%dx%d, slot_size=%d, max_count=%d, hc=%d\n", cldev->tile.size.x, cldev->tile.size.y, cldev->tile_slot_size, cldev->tile_max_count, hc); cldev->tile_hash_table = (tile_hash *)(cldev->tile_data + cldev->tile_data_size) - hc; *************** *** 309,316 **** #ifdef DEBUG private void ! cmd_print_bits(byte *data, int height, int raster) { int i, j; for ( i = 0; i < height; i++ ) ! { byte *row = data + i * raster; dprintf("[L]"); for ( j = 0; j < raster; j++ ) --- 309,316 ---- #ifdef DEBUG private void ! cmd_print_bits(const byte *data, int height, int raster) { int i, j; for ( i = 0; i < height; i++ ) ! { const byte *row = data + i * raster; dprintf("[L]"); for ( j = 0; j < raster; j++ ) *************** *** 343,347 **** int band; for ( band = 0, pcls = cldev->states; band < nbands; band++, pcls++ ) ! { cmd_prefix *cp = pcls->head; if ( cp != 0 ) { cmd_block cb; --- 343,347 ---- int band; for ( band = 0, pcls = cldev->states; band < nbands; band++, pcls++ ) ! { const cmd_prefix *cp = pcls->head; if ( cp != 0 ) { cmd_block cb; *************** *** 348,359 **** cb.band = band; cb.pos = ftell(cfile); ! #ifdef DEBUG ! if ( gs_debug['l'] | gs_debug['L'] ) ! dprintf2("[l]writing for band %d at %ld\n", ! band, cb.pos); ! #endif ! clist_write(bfile, (byte *)&cb, sizeof(cb)); for ( ; cp != 0; cp = cp->next ) ! clist_write(cfile, (byte *)(cp + 1), cp->size); pcls->head = pcls->tail = 0; fputc(cmd_opv_end_run, cfile); --- 348,356 ---- cb.band = band; cb.pos = ftell(cfile); ! if_debug2('l', "[l]writing for band %d at %ld\n", ! band, cb.pos); ! clist_write(bfile, (const byte *)&cb, sizeof(cb)); for ( ; cp != 0; cp = cp->next ) ! clist_write(cfile, (const byte *)(cp + 1), cp->size); pcls->head = pcls->tail = 0; fputc(cmd_opv_end_run, cfile); *************** *** 370,378 **** cmd_put_op(gx_device_clist *cldev, gx_clist_state *pcls, uint size) { byte *dp = cldev->cnext; ! #ifdef DEBUG ! if ( gs_debug['L'] ) ! dprintf3("[L]band %d: size=%u, left=%d", ! (int)(pcls - cldev->states), size, (int)(cldev->cend - dp)); ! #endif if ( size + (sizeof(cmd_prefix) + 4) > cldev->cend - dp ) { cmd_write_buffer(cldev); --- 367,372 ---- cmd_put_op(gx_device_clist *cldev, gx_clist_state *pcls, uint size) { byte *dp = cldev->cnext; ! if_debug3('L', "[L]band %d: size=%u, left=%d", ! (int)(pcls - cldev->states), size, (int)(cldev->cend - dp)); if ( size + (sizeof(cmd_prefix) + 4) > cldev->cend - dp ) { cmd_write_buffer(cldev); *************** *** 405,409 **** /* Write a short bitmap. 1 <= bwidth <= 3. */ private void ! cmd_put_short_bits(register byte *dp, register byte *data, int raster, register int bwidth, register int height) { while ( --height >= 0 ) --- 399,403 ---- /* Write a short bitmap. 1 <= bwidth <= 3. */ private void ! cmd_put_short_bits(register byte *dp, register const byte *data, int raster, register int bwidth, register int height) { while ( --height >= 0 ) *************** *** 527,532 **** /* or 2<=N<=50 for the size of the delta encoding. */ private int ! tile_diff(byte *old_data, byte *new_data, uint tsize, byte _ss *delta) ! { register ushort *old2, *new2; register ushort diff; int count; --- 521,527 ---- /* or 2<=N<=50 for the size of the delta encoding. */ private int ! tile_diff(const byte *old_data, const byte *new_data, uint tsize, ! byte _ss *delta) ! { register const ushort *old2, *new2; register ushort diff; int count; *************** *** 534,539 **** byte _ss *pd; if ( tsize > 128 ) return -1; ! old2 = (ushort *)old_data; ! new2 = (ushort *)new_data; count = 0; pd = delta + 2; /* skip slot index */ --- 529,534 ---- byte _ss *pd; if ( tsize > 128 ) return -1; ! old2 = (const ushort *)old_data; ! new2 = (const ushort *)new_data; count = 0; pd = delta + 2; /* skip slot index */ *************** *** 565,568 **** --- 560,570 ---- #undef b_1 #undef i_hi + if ( count == 0 ) + { /* Tiles are identical. This is highly unusual, */ + /* but not impossible. */ + pd[0] = pd[1] = 0; + pd += 2; + count = 1; + } delta[0] = (byte)cmd_op_delta_tile_bits + count - 1; return pd - delta; *************** *** 574,578 **** private int clist_change_tile(gx_device_clist *cldev, gx_clist_state *pcls, ! gx_bitmap *tile) { uint tile_size = tile->raster * tile->size.y; tile_slot *old_tile, *new_tile; --- 576,580 ---- private int clist_change_tile(gx_device_clist *cldev, gx_clist_state *pcls, ! const gx_bitmap *tile) { uint tile_size = tile->raster * tile->size.y; tile_slot *old_tile, *new_tile; *************** *** 611,621 **** memcpy(ts_bits(cldev, new_tile), tile->data, tile_size); count_add1(cmd_tile_added); ! #ifdef DEBUG ! if ( gs_debug['L'] ) ! dprintf3("[L]adding tile %d, hash=%d, id=%lx\n", slot_index, (int)(hptr - cldev->tile_hash_table), id); - #endif break; } --- 613,620 ---- memcpy(ts_bits(cldev, new_tile), tile->data, tile_size); count_add1(cmd_tile_added); ! if_debug3('L', "[L]adding tile %d, hash=%d, id=%lx\n", slot_index, (int)(hptr - cldev->tile_hash_table), id); break; } *************** *** 623,630 **** if ( new_tile->id == id ) { count_add1(cmd_tile_found); ! #ifdef DEBUG ! if ( gs_debug['L'] ) ! dprintf1("[L]found tile %d\n", slot_index); ! #endif break; } --- 622,627 ---- if ( new_tile->id == id ) { count_add1(cmd_tile_found); ! if_debug1('L', "[L]found tile %d\n", ! slot_index); break; } *************** *** 686,690 **** } private int ! clist_tile_rectangle(gx_device *dev, gx_bitmap *tile, int x, int y, int width, int height, gx_color_index color0, gx_color_index color1, int px, int py) --- 683,687 ---- } private int ! clist_tile_rectangle(gx_device *dev, const gx_bitmap *tile, int x, int y, int width, int height, gx_color_index color0, gx_color_index color1, int px, int py) *************** *** 710,714 **** private int clist_copy_mono(gx_device *dev, ! byte *data, int data_x, int raster, gx_bitmap_id id, int x, int y, int width, int height, gx_color_index color0, gx_color_index color1) --- 707,711 ---- private int clist_copy_mono(gx_device *dev, ! const byte *data, int data_x, int raster, gx_bitmap_id id, int x, int y, int width, int height, gx_color_index color0, gx_color_index color1) *************** *** 718,722 **** uint dsize; int bwidth; ! byte *row = data + (y - y0) * raster; byte *dp; if ( color0 != pcls->color0 || color1 != pcls->color1 ) --- 715,719 ---- uint dsize; int bwidth; ! const byte *row = data + (y - y0) * raster; byte *dp; if ( color0 != pcls->color0 || color1 != pcls->color1 ) *************** *** 735,738 **** --- 732,737 ---- row += data_x >> 3; cmd_put_short_bits(dp, row, raster, bwidth, height); + pcls->rect = rect; + count_add(cmd_copy_count, dsize); } else *************** *** 742,749 **** if ( height > 1 ) { int h2 = height >> 1; ! clist_copy_mono(dev, data, data_x, raster, gx_no_bitmap_id, x, y, width, h2, color0, color1); ! return clist_copy_mono(dev, data + h2 * raster, data_x, raster, gx_no_bitmap_id, x, y + h2, width, height - h2, --- 741,748 ---- if ( height > 1 ) { int h2 = height >> 1; ! clist_copy_mono(dev, row, data_x, raster, gx_no_bitmap_id, x, y, width, h2, color0, color1); ! clist_copy_mono(dev, row + h2 * raster, data_x, raster, gx_no_bitmap_id, x, y + h2, width, height - h2, *************** *** 752,759 **** /* Split a single (very long) row. */ { int w2 = width >> 1; ! clist_copy_mono(dev, data, data_x, raster, gx_no_bitmap_id, x, y, w2, 1, color0, color1); ! return clist_copy_mono(dev, data, data_x + w2, raster, gx_no_bitmap_id, x + w2, y, width - w2, 1, color0, color1); --- 751,758 ---- /* Split a single (very long) row. */ { int w2 = width >> 1; ! clist_copy_mono(dev, row, data_x, raster, gx_no_bitmap_id, x, y, w2, 1, color0, color1); ! clist_copy_mono(dev, row, data_x + w2, raster, gx_no_bitmap_id, x + w2, y, width - w2, 1, color0, color1); *************** *** 760,773 **** } } ! dp = cmd_put_op(cdev, pcls, 1 + sizeof(rect) + 4 + dsize); ! count_op(*dp++ = (byte)cmd_op_copy_mono); ! memcpy(dp, (byte *)&rect, sizeof(rect)); ! dp += sizeof(rect); ! cmd_putw(data_x, dp); ! cmd_putw(raster, dp); ! memcpy(dp, row, dsize); } - pcls->rect = rect; - count_add(cmd_copy_count, dsize); END_RECT return 0; --- 759,774 ---- } } ! else ! { dp = cmd_put_op(cdev, pcls, 1 + sizeof(rect) + 4 + dsize); ! count_op(*dp++ = (byte)cmd_op_copy_mono); ! memcpy(dp, (byte *)&rect, sizeof(rect)); ! dp += sizeof(rect); ! cmd_putw(data_x, dp); ! cmd_putw(raster, dp); ! memcpy(dp, row, dsize); ! pcls->rect = rect; ! count_add(cmd_copy_count, dsize); ! } } END_RECT return 0; *************** *** 776,780 **** private int clist_copy_color(gx_device *dev, ! byte *data, int data_x, int raster, gx_bitmap_id id, int x, int y, int width, int height) { int y0 = y; --- 777,781 ---- private int clist_copy_color(gx_device *dev, ! const byte *data, int data_x, int raster, gx_bitmap_id id, int x, int y, int width, int height) { int y0 = y; *************** *** 782,785 **** --- 783,787 ---- gx_cmd_rect rect; uint dsize = height * raster; + const byte *row = data + (y - y0) * raster; byte *dp; if ( dsize > cbuf_size ) *************** *** 787,814 **** if ( height > 1 ) { int h2 = height >> 1; ! clist_copy_color(dev, data, data_x, raster, gx_no_bitmap_id, x, y, width, h2); ! return clist_copy_color(dev, data + h2 * raster, gx_no_bitmap_id, data_x, raster, x, y + h2, width, height - h2); } ! /* Split a single (very long) row. */ ! { int w2 = width >> 1; ! clist_copy_color(dev, data, data_x, raster, gx_no_bitmap_id, x, y, w2, 1); ! return clist_copy_color(dev, data, data_x + w2, raster, gx_no_bitmap_id, x + w2, y, width - w2, 1); } - } ! cmd_set_rect(rect); ! dp = cmd_put_op(cdev, pcls, 1 + sizeof(rect) + 4 + dsize); ! count_op(*dp++ = (byte)cmd_op_copy_color); ! memcpy(dp, (byte *)&rect, sizeof(rect)); ! pcls->rect = rect; ! dp += sizeof(rect); ! cmd_putw(data_x, dp); ! cmd_putw(raster, dp); ! memcpy(dp, data + (y - y0) * raster, dsize); END_RECT return 0; --- 789,819 ---- if ( height > 1 ) { int h2 = height >> 1; ! clist_copy_color(dev, row, data_x, raster, gx_no_bitmap_id, x, y, width, h2); ! clist_copy_color(dev, row + h2 * raster, gx_no_bitmap_id, data_x, raster, x, y + h2, width, height - h2); } ! else ! { /* Split a single (very long) row. */ ! int w2 = width >> 1; ! clist_copy_color(dev, row, data_x, raster, gx_no_bitmap_id, x, y, w2, 1); ! clist_copy_color(dev, row, data_x + w2, raster, gx_no_bitmap_id, x + w2, y, width - w2, 1); } } ! else ! { cmd_set_rect(rect); ! dp = cmd_put_op(cdev, pcls, 1 + sizeof(rect) + 4 + dsize); ! count_op(*dp++ = (byte)cmd_op_copy_color); ! memcpy(dp, (byte *)&rect, sizeof(rect)); ! pcls->rect = rect; ! dp += sizeof(rect); ! cmd_putw(data_x, dp); ! cmd_putw(raster, dp); ! memcpy(dp, row, dsize); ! count_add(cmd_copy_count, dsize); ! } END_RECT return 0; *************** *** 882,886 **** int depth = target->color_info.depth; uint raster = ((target->width * depth + 31) >> 5) << 2; ! gx_device_memory *mdev = gdev_mem_device_for_bits(depth); if ( mdev == 0 ) return_error(gs_error_rangecheck); --- 887,891 ---- int depth = target->color_info.depth; uint raster = ((target->width * depth + 31) >> 5) << 2; ! const gx_device_memory *mdev = gdev_mem_device_for_bits(depth); if ( mdev == 0 ) return_error(gs_error_rangecheck); *************** *** 992,999 **** } op = *cbp++; ! #ifdef DEBUG ! if ( gs_debug['L'] ) ! dprintf2("[L]%s %d:\n", cmd_op_names[op >> 4], op & 0xf); ! #endif switch ( op >> 4 ) { --- 997,1002 ---- } op = *cbp++; ! if_debug2('L', "[L]%s %d:\n", ! cmd_op_names[op >> 4], op & 0xf); switch ( op >> 4 ) { *************** *** 1106,1127 **** } continue; default: ! bad_op: printf/*lprintf5*/("Bad op %02x band %d file pos %ld buf pos %d/%d\n", op, band, ftell(file), (int)(cbp - cbuf), (int)(cb_end - cbuf)); { cb_ptr pp; for ( pp = cbuf; pp < cb_end; pp += 10 ) ! printf/*lprintf10*/(" %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", pp[0], pp[1], pp[2], pp[3], pp[4], pp[5], pp[6], pp[7], pp[8], pp[9]); } ! ! gs_exit(1); ! return -1; } ! #ifdef DEBUG ! if ( gs_debug['L'] ) ! dprintf4("[L] x=%d y=%d w=%d h=%d\n", ! state.rect.x, state.rect.y, state.rect.width, ! state.rect.height); ! #endif switch ( op >> 4 ) { --- 1109,1125 ---- } continue; default: ! bad_op: lprintf5("Bad op %02x band %d file pos %ld buf pos %d/%d\n", op, band, ftell(file), (int)(cbp - cbuf), (int)(cb_end - cbuf)); { cb_ptr pp; for ( pp = cbuf; pp < cb_end; pp += 10 ) ! lprintf10(" %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", pp[0], pp[1], pp[2], pp[3], pp[4], pp[5], pp[6], pp[7], pp[8], pp[9]); } ! return_error(gs_error_Fatal); } ! if_debug4('L', "[L] x=%d y=%d w=%d h=%d\n", ! state.rect.x, state.rect.y, state.rect.width, ! state.rect.height); switch ( op >> 4 ) { diff -rc2N gs241/gxcolor.c gs25/gxcolor.c *** gs241/gxcolor.c Fri Apr 10 15:56:16 1992 --- gs25/gxcolor.c Thu Jul 16 17:56:50 1992 *************** *** 27,30 **** --- 27,31 ---- #include "gxdevice.h" /* for gx_color_index */ #include "gzcolor.h" + #include "gscspace.h" #include "gzht.h" #include "gzstate.h" *************** *** 99,103 **** /* Map a color_param through a transfer map. */ color_param ! gx_color_param_map(color_param cv, color_param *values) { #define cp_frac_bits (color_param_bits - log2_transfer_map_size) --- 100,104 ---- /* Map a color_param through a transfer map. */ color_param ! gx_color_param_map(color_param cv, const color_param *values) { #define cp_frac_bits (color_param_bits - log2_transfer_map_size) *************** *** 123,130 **** int gx_remap_color(gs_state *pgs) ! { gs_color *pcolor = pgs->color; gs_color mcolor; /* color mapped by transfer procs */ #define mapcp(p,c) gx_map_color_param(pgs, pcolor->c, p) ! switch ( (gs_color_space)pcolor->space ) { case gs_color_space_DeviceGray: --- 124,131 ---- int gx_remap_color(gs_state *pgs) ! { const gs_color *pcolor = pgs->color; gs_color mcolor; /* color mapped by transfer procs */ #define mapcp(p,c) gx_map_color_param(pgs, pcolor->c, p) ! switch ( (gs_color_space_type)pcolor->space ) { case gs_color_space_DeviceGray: *************** *** 132,135 **** --- 133,137 ---- break; case gs_color_space_DeviceRGB: + case gs_color_space_DeviceCMYK: /* BOGUS */ gx_set_rgb_only(&mcolor, mapcp(red, red), mapcp(green, green), mapcp(blue, blue)); *************** *** 169,173 **** /* Convert RGB to HSB */ void ! gx_color_to_hsb(register gs_color *pcolor, color_param hsb[3]) { #define rhue hsb[0] --- 171,175 ---- /* Convert RGB to HSB */ void ! gx_color_to_hsb(register const gs_color *pcolor, color_param hsb[3]) { #define rhue hsb[0] diff -rc2N gs241/gxcpath.c gs25/gxcpath.c *** gs241/gxcpath.c Wed Apr 15 13:19:22 1992 --- gs25/gxcpath.c Sun Aug 9 05:53:18 1992 *************** *** 95,99 **** /* Return the quick-check rectangle for a clipping path. */ int ! gx_cpath_box_for_check(gx_clip_path *pcpath, gs_fixed_rect *pbox) { *pbox = pcpath->cbox; return 0; --- 95,99 ---- /* Return the quick-check rectangle for a clipping path. */ int ! gx_cpath_box_for_check(const gx_clip_path *pcpath, gs_fixed_rect *pbox) { *pbox = pcpath->cbox; return 0; *************** *** 103,107 **** /* The rectangle need not be oriented correctly, i.e. x0 > x1 is OK. */ int ! gx_cpath_includes_rectangle(register gx_clip_path *pcpath, fixed x0, fixed y0, fixed x1, fixed y1) { return --- 103,107 ---- /* The rectangle need not be oriented correctly, i.e. x0 > x1 is OK. */ int ! gx_cpath_includes_rectangle(register const gx_clip_path *pcpath, fixed x0, fixed y0, fixed x1, fixed y1) { return *************** *** 133,137 **** /* but it will be oriented correctly upon return. */ int ! gx_cpath_from_rectangle(gx_clip_path *pcpath, gs_fixed_rect *pbox, gs_memory_procs *mp) { gx_clip_list_from_rectangle(&pcpath->list, pbox); pcpath->cbox = *pbox; --- 133,137 ---- /* but it will be oriented correctly upon return. */ int ! gx_cpath_from_rectangle(gx_clip_path *pcpath, gs_fixed_rect *pbox, const gs_memory_procs *mp) { gx_clip_list_from_rectangle(&pcpath->list, pbox); pcpath->cbox = *pbox; *************** *** 144,151 **** /* Intersect a new clipping path with an old one. */ ! /* Note that it may overwrite its path argument. */ int gx_cpath_intersect(gs_state *pgs, gx_clip_path *pcpath, gx_path *ppath, int rule) { gs_fixed_rect old_box, new_box; if ( gx_cpath_is_rectangle(pcpath, &old_box) && gx_path_is_rectangle(ppath, &new_box) --- 144,153 ---- /* Intersect a new clipping path with an old one. */ ! /* Note that it may overwrite its path argument; return 1 in this case, */ ! /* otherwise 0 for success, <0 for failure as usual. */ int gx_cpath_intersect(gs_state *pgs, gx_clip_path *pcpath, gx_path *ppath, int rule) { gs_fixed_rect old_box, new_box; + int code; if ( gx_cpath_is_rectangle(pcpath, &old_box) && gx_path_is_rectangle(ppath, &new_box) *************** *** 180,183 **** --- 182,186 ---- pcpath->path = *ppath; pcpath->segments_valid = 1; + code = 1; } else *************** *** 186,190 **** gx_device_color devc; gx_device *save_dev = gs_currentdevice(pgs); - int code; adev = gs_accum_device; adev.memory_procs = pcpath->path.memory_procs; --- 189,192 ---- *************** *** 194,198 **** devc.halftone_level = 0; gx_set_device_only(pgs, (gx_device *)&adev); ! code = gx_fill_path(ppath, &devc, pgs, rule, (fixed)0); gx_set_device_only(pgs, save_dev); if ( code < 0 ) return code; --- 196,200 ---- devc.halftone_level = 0; gx_set_device_only(pgs, (gx_device *)&adev); ! code = gx_fill_path(ppath, &devc, pgs, rule, fixed_half); gx_set_device_only(pgs, save_dev); if ( code < 0 ) return code; *************** *** 218,223 **** pcpath->segments_valid = 0; pcpath->shares_list = 0; } ! return 0; } --- 220,226 ---- pcpath->segments_valid = 0; pcpath->shares_list = 0; + code = 0; } ! return code; } *************** *** 240,247 **** if ( rp->p.y > rp->q.y ) { fixed t = rp->p.y; rp->p.y = rp->q.y; rp->q.y = t; } ! clp->sole.xmin = fixed2int_var_rounded(rp->p.x); ! clp->sole.ymin = fixed2int_var_rounded(rp->p.y); ! clp->sole.xmax = fixed2int_var_rounded(rp->q.x); ! clp->sole.ymax = fixed2int_var_rounded(rp->q.y); clp->count = 1; } --- 243,250 ---- if ( rp->p.y > rp->q.y ) { fixed t = rp->p.y; rp->p.y = rp->q.y; rp->q.y = t; } ! clp->sole.xmin = fixed2int_var(rp->p.x); ! clp->sole.ymin = fixed2int_var(rp->p.y); ! clp->sole.xmax = fixed2int_var_ceiling(rp->q.x); ! clp->sole.ymax = fixed2int_var_ceiling(rp->q.y); clp->count = 1; } *************** *** 269,273 **** /* Free a clip list. */ void ! gx_clip_list_free(gx_clip_list *clp, gs_memory_procs *mp) { gx_clip_rect *rp = clp->last.prev; if ( clp->count <= 1 ) return; --- 272,276 ---- /* Free a clip list. */ void ! gx_clip_list_free(gx_clip_list *clp, const gs_memory_procs *mp) { gx_clip_rect *rp = clp->last.prev; if ( clp->count <= 1 ) return; *************** *** 551,554 **** --- 554,559 ---- * the clipping region. Usage: * BEGIN_CLIP + * (adjust for yc > y if necessary) + * FOR_CLIP * ... xc, yc, xec, yec ... [must be an expression statement] * NEXT_CLIP *************** *** 570,574 **** yc = rptr->ymin;\ if ( yc < y ) yc = y;\ ! else if ( yc >= ye ) return 0;\ for ( ; ; )\ { const int ymax = rptr->ymax;\ --- 575,580 ---- yc = rptr->ymin;\ if ( yc < y ) yc = y;\ ! else if ( yc >= ye ) return 0; ! #define FOR_CLIP\ for ( ; ; )\ { const int ymax = rptr->ymax;\ *************** *** 644,647 **** --- 650,654 ---- return (*fill)(tdev, x, y, w, h, color); BEGIN_CLIP + FOR_CLIP (*fill)(tdev, xc, yc, xec - xc, yec - yc, color); NEXT_CLIP *************** *** 652,656 **** /* Tile a rectangle */ private int ! clip_tile_rectangle(gx_device *dev, gx_bitmap *tile, int x, int y, int w, int h, gx_color_index color0, gx_color_index color1, int phase_x, int phase_y) --- 659,663 ---- /* Tile a rectangle */ private int ! clip_tile_rectangle(gx_device *dev, const gx_bitmap *tile, int x, int y, int w, int h, gx_color_index color0, gx_color_index color1, int phase_x, int phase_y) *************** *** 660,663 **** --- 667,671 ---- return (*fill)(tdev, tile, x, y, w, h, color0, color1, phase_x, phase_y); BEGIN_CLIP + FOR_CLIP (*fill)(tdev, tile, xc, yc, xec - xc, yec - yc, color0, color1, phase_x, phase_y); NEXT_CLIP *************** *** 669,673 **** private int clip_copy_mono(gx_device *dev, ! byte *data, int sourcex, int raster, gx_bitmap_id id, int x, int y, int w, int h, gx_color_index color0, gx_color_index color1) --- 677,681 ---- private int clip_copy_mono(gx_device *dev, ! const byte *data, int sourcex, int raster, gx_bitmap_id id, int x, int y, int w, int h, gx_color_index color0, gx_color_index color1) *************** *** 677,680 **** --- 685,690 ---- return (*copy)(tdev, data, sourcex, raster, id, x, y, w, h, color0, color1); BEGIN_CLIP + if ( yc > y ) data += (yc - y) * raster; + FOR_CLIP (*copy)(tdev, data, sourcex + xc - x, raster, gx_no_bitmap_id, xc, yc, xec - xc, yec - yc, color0, color1); NEXT_CLIP *************** *** 687,691 **** private int clip_copy_color(gx_device *dev, ! byte *data, int sourcex, int raster, gx_bitmap_id id, int x, int y, int w, int h) { DECLARE_CLIP --- 697,701 ---- private int clip_copy_color(gx_device *dev, ! const byte *data, int sourcex, int raster, gx_bitmap_id id, int x, int y, int w, int h) { DECLARE_CLIP *************** *** 694,697 **** --- 704,709 ---- return (*copy)(tdev, data, sourcex, raster, id, x, y, w, h); BEGIN_CLIP + if ( yc > y ) data += (yc - y) * raster; + FOR_CLIP (*copy)(tdev, data, sourcex + xc - x, raster, gx_no_bitmap_id, xc, yc, xec - xc, yec - yc); NEXT_CLIP diff -rc2N gs241/gxdevice.h gs25/gxdevice.h *** gs241/gxdevice.h Tue Apr 7 15:41:20 1992 --- gs25/gxdevice.h Sat Aug 15 08:57:50 1992 *************** *** 90,94 **** #endif ! /* Definition of device procedures */ struct gx_device_procs_s { --- 90,97 ---- #endif ! /* Definition of device procedures. */ ! /* Note that the gx_device * argument is not declared const, */ ! /* because many drivers maintain dynamic state in the device structure. */ ! struct gx_device_procs_s { *************** *** 130,134 **** #define dev_proc_tile_rectangle(proc)\ int proc(P10(gx_device *dev,\ ! gx_bitmap *tile, int x, int y, int width, int height,\ gx_color_index color0, gx_color_index color1,\ int phase_x, int phase_y)) --- 133,137 ---- #define dev_proc_tile_rectangle(proc)\ int proc(P10(gx_device *dev,\ ! const gx_bitmap *tile, int x, int y, int width, int height,\ gx_color_index color0, gx_color_index color1,\ int phase_x, int phase_y)) *************** *** 137,141 **** #define dev_proc_copy_mono(proc)\ int proc(P11(gx_device *dev,\ ! unsigned char *data, int data_x, int raster, gx_bitmap_id id,\ int x, int y, int width, int height,\ gx_color_index color0, gx_color_index color1)) --- 140,144 ---- #define dev_proc_copy_mono(proc)\ int proc(P11(gx_device *dev,\ ! const unsigned char *data, int data_x, int raster, gx_bitmap_id id,\ int x, int y, int width, int height,\ gx_color_index color0, gx_color_index color1)) *************** *** 144,148 **** #define dev_proc_copy_color(proc)\ int proc(P9(gx_device *dev,\ ! unsigned char *data, int data_x, int raster, gx_bitmap_id id,\ int x, int y, int width, int height)) dev_proc_copy_color((*copy_color)); --- 147,151 ---- #define dev_proc_copy_color(proc)\ int proc(P9(gx_device *dev,\ ! const unsigned char *data, int data_x, int raster, gx_bitmap_id id,\ int x, int y, int width, int height)) dev_proc_copy_color((*copy_color)); *************** *** 170,174 **** /* Calculate the number of bytes in a scan line, */ /* with byte or word padding. */ ! extern unsigned int gx_device_bytes_per_scan_line(P2(gx_device *dev, int pad_to_word)); /* Default implementations of optional procedures */ --- 173,181 ---- /* Calculate the number of bytes in a scan line, */ /* with byte or word padding. */ ! extern unsigned int gx_device_bytes_per_scan_line(P2(const gx_device *dev, int pad_to_word)); ! ! /* Adjust the resolution for devices that only have a fixed set of */ ! /* geometries, so that the apparent size in inches remains constant. */ ! extern int gx_device_adjust_resolution(P3(gx_device *dev, int actual_width, int actual_height)); /* Default implementations of optional procedures */ diff -rc2N gs241/gxdevmem.h gs25/gxdevmem.h *** gs241/gxdevmem.h Sat Apr 18 15:42:32 1992 --- gs25/gxdevmem.h Thu May 28 11:41:20 1992 *************** *** 43,47 **** gs_matrix initial_matrix; /* the initial transformation */ uint raster; /* bytes per scan line, */ ! /* filled in by '...bitmap_size' */ byte *base; byte **line_ptrs; /* scan line pointers */ --- 43,47 ---- gs_matrix initial_matrix; /* the initial transformation */ uint raster; /* bytes per scan line, */ ! /* filled in by 'open' */ byte *base; byte **line_ptrs; /* scan line pointers */ *************** *** 55,59 **** byte *palette; /* RGB triples */ }; ! extern gx_device_memory mem_mono_device, mem_mapped2_color_device, --- 55,59 ---- byte *palette; /* RGB triples */ }; ! extern const gx_device_memory mem_mono_device, mem_mapped2_color_device, *************** *** 64,76 **** mem_true32_color_device; ! /* Memory devices may have special setup requirements. */ ! /* In particular, it may not be obvious how much space to allocate */ ! /* for the bitmap. Here is the routine that computes this */ ! /* from the width and height in the device structure. */ ! extern ulong gdev_mem_bitmap_size(P1(gx_device_memory *)); /* Determine the appropriate memory device for a given */ /* number of bits per pixel (0 if none suitable). */ ! extern gx_device_memory *gdev_mem_device_for_bits(P1(int)); /* Test whether a device is a memory device. */ --- 64,82 ---- mem_true32_color_device; ! /* ! * Memory devices may have special setup requirements. ! * In particular, it may not be obvious how much space to allocate ! * for the bitmap. Here is the routine that computes this ! * from the width and height in the device structure. ! */ ! extern ulong gdev_mem_bitmap_size(P1(const gx_device_memory *)); ! /* ! * Compute the raster (bytes per line) similarly. ! */ ! extern uint gdev_mem_raster(P1(const gx_device_memory *)); /* Determine the appropriate memory device for a given */ /* number of bits per pixel (0 if none suitable). */ ! extern const gx_device_memory *gdev_mem_device_for_bits(P1(int)); /* Test whether a device is a memory device. */ diff -rc2N gs241/gxdither.c gs25/gxdither.c *** gs241/gxdither.c Fri Apr 10 15:56:26 1992 --- gs25/gxdither.c Thu Apr 30 17:51:16 1992 *************** *** 68,72 **** */ ! void gx_color_load(P2(gx_device_color *, gs_state *)); #define WEIGHT1 (unsigned long)(100) /* 1.0 */ --- 68,72 ---- */ ! extern void gx_color_load(P2(gx_device_color *, gs_state *)); #define WEIGHT1 (unsigned long)(100) /* 1.0 */ *************** *** 82,86 **** #define DIAG_RGB (0x7) ! static unsigned short lum[8] = { (0*lum_blue_weight+0*lum_green_weight+0*lum_red_weight), (0*lum_blue_weight+0*lum_green_weight+1*lum_red_weight), --- 82,86 ---- #define DIAG_RGB (0x7) ! private const unsigned short lum_w[8] = { (0*lum_blue_weight+0*lum_green_weight+0*lum_red_weight), (0*lum_blue_weight+0*lum_green_weight+1*lum_red_weight), *************** *** 99,119 **** /* We have to split up the following because of a bug in the IBM AIX 3.2 */ /* C compiler. */ ! private gx_color_value q0[] = { 0 }; ! private gx_color_value q1[] = { 0, 0xffff }; ! private gx_color_value q2[] = { 0, _fc(1,2), 0xffff }; ! private gx_color_value q3[] = { 0, _fc(1,3), _fc(2,3), 0xffff }; ! private gx_color_value q4[] = { 0, _fc(1,4), _fc(2,4), _fc(3,4), 0xffff }; ! private gx_color_value q5[] = { 0, _fc(1,5), _fc(2,5), _fc(3,5), _fc(4,5), 0xffff }; ! private gx_color_value q6[] = { 0, _fc(1,6), _fc(2,6), _fc(3,6), _fc(4,6), _fc(5,6), 0xffff }; ! private gx_color_value q7[] = { 0, _fc(1,7), _fc(2,7), _fc(3,7), _fc(4,7), _fc(5,7), _fc(6,7), 0xffff }; ! private gx_color_value _ds *color_quo[8] = { q0, q1, q2, q3, q4, q5, q6, q7 }; #define fractional_color(f, maxv)\ ((maxv) <= 7 ? color_quo[maxv][f] : _fc(f, maxv)) --- 99,120 ---- /* We have to split up the following because of a bug in the IBM AIX 3.2 */ /* C compiler. */ ! private const gx_color_value q0[] = { 0 }; ! private const gx_color_value q1[] = { 0, 0xffff }; ! private const gx_color_value q2[] = { 0, _fc(1,2), 0xffff }; ! private const gx_color_value q3[] = { 0, _fc(1,3), _fc(2,3), 0xffff }; ! private const gx_color_value q4[] = { 0, _fc(1,4), _fc(2,4), _fc(3,4), 0xffff }; ! private const gx_color_value q5[] = { 0, _fc(1,5), _fc(2,5), _fc(3,5), _fc(4,5), 0xffff }; ! private const gx_color_value q6[] = { 0, _fc(1,6), _fc(2,6), _fc(3,6), _fc(4,6), _fc(5,6), 0xffff }; ! private const gx_color_value q7[] = { 0, _fc(1,7), _fc(2,7), _fc(3,7), _fc(4,7), _fc(5,7), _fc(6,7), 0xffff }; ! private const gx_color_value _ds *color_quo[8] = ! { q0, q1, q2, q3, q4, q5, q6, q7 }; #define fractional_color(f, maxv)\ ((maxv) <= 7 ? color_quo[maxv][f] : _fc(f, maxv)) *************** *** 266,279 **** return; } ! #ifdef DEBUG ! if ( gs_debug['c'] ) ! { dprintf3("[c]rgb=%x,%x,%x -->\n", ! (unsigned)pcolor->red, (unsigned)pcolor->green, ! (unsigned)pcolor->blue); ! dprintf6(" %x+%x,%x+%x,%x+%x -->\n", ! (unsigned)r, (unsigned)rem_r, (unsigned)g, (unsigned)rem_g, ! (unsigned)b, (unsigned)rem_b); ! } ! #endif /* flip the remainder color into the 0, 0, 0 octant */ --- 267,276 ---- return; } ! ! if_debug9('c', "[c]rgb=%x,%x,%x -->\n %x+%x,%x+%x,%x+%x -->\n", ! (unsigned)pcolor->red, (unsigned)pcolor->green, ! (unsigned)pcolor->blue, ! (unsigned)r, (unsigned)rem_r, (unsigned)g, (unsigned)rem_g, ! (unsigned)b, (unsigned)rem_b); /* flip the remainder color into the 0, 0, 0 octant */ *************** *** 341,354 **** level = (hsize * dmax) / (2 * max_color_param_long); }; - #ifdef DEBUG - if ( gs_debug['c'] ) - { dprintf6(" %x+%x,%x+%x,%x+%x;", - (unsigned)r, (unsigned)rem_r, (unsigned)g, (unsigned)rem_g, - (unsigned)b, (unsigned)rem_b); - dprintf3(" adjust=%d,%d,%d;\n", - adjust_r, adjust_g, adjust_b); - } - #endif if ( (pdevc->halftone_level = level) == 0 ) pdevc->color2 = pdevc->color1; --- 338,347 ---- level = (hsize * dmax) / (2 * max_color_param_long); }; + if_debug9('c', " %x+%x,%x+%x,%x+%x; adjust=%d,%d,%d;\n", + (unsigned)r, (unsigned)rem_r, (unsigned)g, (unsigned)rem_g, + (unsigned)b, (unsigned)rem_b, + adjust_r, adjust_g, adjust_b); + if ( (pdevc->halftone_level = level) == 0 ) pdevc->color2 = pdevc->color1; *************** *** 365,369 **** /****** THIS IS A BAD IDEA ******/ #if 0 ! if ( lum[diagc] < lum_invert ) { pdevc->color2 = pdevc->color1; pdevc->color1 = color2; --- 358,362 ---- /****** THIS IS A BAD IDEA ******/ #if 0 ! if ( lum_w[diagc] < lum_invert ) { pdevc->color2 = pdevc->color1; pdevc->color1 = color2; *************** *** 376,386 **** } ! #ifdef DEBUG ! if ( gs_debug['c'] ) ! { dprintf5("[c]diagc=%d; color1=%lx, color2=%lx, level=%d/%d\n", ! diagc, (ulong)pdevc->color1, (ulong)pdevc->color2, ! level, (unsigned)hsize); ! } ! #endif } --- 369,375 ---- } ! if_debug5('c', "[c]diagc=%d; color1=%lx, color2=%lx, level=%d/%d\n", ! diagc, (ulong)pdevc->color1, (ulong)pdevc->color2, ! level, (unsigned)hsize); } diff -rc2N gs241/gxdraw.c gs25/gxdraw.c *** gs241/gxdraw.c Mon Mar 16 17:08:28 1992 --- gs25/gxdraw.c Sat Jun 20 02:09:50 1992 *************** *** 22,25 **** --- 22,26 ---- #include "gx.h" #include "math_.h" + #include "gpcheck.h" #include "gxfixed.h" #include "gxmatrix.h" *************** *** 30,42 **** /* Fill a rectangle. */ int ! gz_fill_rectangle(int x, int y, int w, int h, gx_device_color *pdevc, gs_state *pgs) { gx_device *dev = pgs->device->info; ! #ifdef DEBUG ! if ( gs_debug['v'] ) ! dprintf7("[v]x=%d y=%d w=%d h=%d c1=%ld c2=%ld htl=%d\n", ! x, y, w, h, (long)pdevc->color1, (long)pdevc->color2, ! (long)pdevc->halftone_level); ! #endif return gz_fill_rectangle_open(dev, x, y, w, h, dev->procs->fill_rectangle, dev->procs->tile_rectangle, pdevc, pgs); } --- 31,40 ---- /* Fill a rectangle. */ int ! gz_fill_rectangle(int x, int y, int w, int h, const gx_device_color *pdevc, gs_state *pgs) { gx_device *dev = pgs->device->info; ! if_debug7('v', "[v]x=%d y=%d w=%d h=%d c1=%ld c2=%ld htl=%d\n", ! x, y, w, h, (long)pdevc->color1, (long)pdevc->color2, ! (long)pdevc->halftone_level); return gz_fill_rectangle_open(dev, x, y, w, h, dev->procs->fill_rectangle, dev->procs->tile_rectangle, pdevc, pgs); } *************** *** 74,79 **** gz_fill_trapezoid_fixed(fixed fx0, fixed fw0, fixed fy0, fixed fx1, fixed fw1, fixed fh, int swap_axes, ! gx_device_color *pdevc, gs_state *pgs) ! { const fixed ymin = fixed_rounded(fy0) + float2fixed(0.5); const fixed ymax = fixed_rounded(fy0 + fh); int iy = fixed2int_var(ymin); --- 72,77 ---- gz_fill_trapezoid_fixed(fixed fx0, fixed fw0, fixed fy0, fixed fx1, fixed fw1, fixed fh, int swap_axes, ! const gx_device_color *pdevc, gs_state *pgs) ! { const fixed ymin = fixed_rounded(fy0) + fixed_half; const fixed ymax = fixed_rounded(fy0 + fh); int iy = fixed2int_var(ymin); *************** *** 91,96 **** dev_proc_fill_rectangle((*fill_rect)); int code; - r.x = (l.x = fx0 + float2fixed(0.5)) + fw0; if ( fill_direct ) cindex = pdevc->color1, --- 89,95 ---- dev_proc_fill_rectangle((*fill_rect)); int code; + + if_debug2('z', "[z]y=[%d,%d]\n", iy, iy1); if ( fill_direct ) cindex = pdevc->color1, *************** *** 97,100 **** --- 96,115 ---- dev = pgs->device->info, fill_rect = dev->procs->fill_rectangle; + gp_check_interrupts(); + r.x = (l.x = fx0 + fixed_half) + fw0; + ry = iy; + + /* If the rounded X values are the same on both sides, */ + /* we can save ourselves a *lot* of work. */ + if ( fixed_truncated(l.x) == fixed_rounded(fx1) && + fixed_truncated(r.x) == fixed_rounded(fx1 + fw1) + ) + { rxl = fixed2int_var(l.x); + rxr = fixed2int_var(r.x); + iy = iy1; + if_debug2('z', "[z]rectangle, x=[%d,%d]\n", rxl, rxr); + goto last; + } + #define fill_trap_rect(x,y,w,h)\ (fill_direct ?\ *************** *** 147,151 **** rxl = fixed2int_var(l.x); rxr = fixed2int_var(r.x); - ry = iy; /* Compute one line's worth of dx/dy. */ --- 162,165 ---- *************** *** 191,195 **** } last: code = fill_trap_rect(rxl, ry, rxr - rxl, iy - ry); ! xit: if ( code < 0 && fill_direct ) return_error(code); return code; } --- 205,210 ---- } last: code = fill_trap_rect(rxl, ry, rxr - rxl, iy - ry); ! xit: gp_check_interrupts(); ! if ( code < 0 && fill_direct ) return_error(code); return code; } *************** *** 200,204 **** int gz_fill_pgram_fixed(fixed px, fixed py, fixed ax, fixed ay, ! fixed bx, fixed by, gx_device_color *pdevc, gs_state *pgs) { fixed t; fixed qx, dx, wx, pax, qax; --- 215,219 ---- int gz_fill_pgram_fixed(fixed px, fixed py, fixed ax, fixed ay, ! fixed bx, fixed by, const gx_device_color *pdevc, gs_state *pgs) { fixed t; fixed qx, dx, wx, pax, qax; *************** *** 238,242 **** /* Default implementation of tile_rectangle */ int ! gx_default_tile_rectangle(gx_device *dev, register gx_bitmap *tile, int x, int y, int w, int h, gx_color_index color0, gx_color_index color1, int px, int py) --- 253,257 ---- /* Default implementation of tile_rectangle */ int ! gx_default_tile_rectangle(gx_device *dev, register const gx_bitmap *tile, int x, int y, int w, int h, gx_color_index color0, gx_color_index color1, int px, int py) *************** *** 267,271 **** if ( gs_debug['t'] ) { int ptx, pty; ! byte *ptp = tile->data; dprintf3("[t]tile %dx%d raster=%d;", tile->size.x, tile->size.y, tile->raster); --- 282,286 ---- if ( gs_debug['t'] ) { int ptx, pty; ! const byte *ptp = tile->data; dprintf3("[t]tile %dx%d raster=%d;", tile->size.x, tile->size.y, tile->raster); *************** *** 285,288 **** --- 300,304 ---- (*proc_color)(dev, row, srcx, raster, gx_no_bitmap_id, tx, ty, tw, th) :\ (*proc_mono)(dev, row, srcx, raster, gx_no_bitmap_id, tx, ty, tw, th, color0, color1));\ + gp_check_interrupts();\ if ( code < 0 ) return_error(code) #ifdef DEBUG *************** *** 366,370 **** int gz_draw_line_fixed(fixed ixf, fixed iyf, fixed itoxf, fixed itoyf, ! gx_device_color *pdevc, gs_state *pgs) { int ix = fixed2int_var(ixf); int iy = fixed2int_var(iyf); --- 382,386 ---- int gz_draw_line_fixed(fixed ixf, fixed iyf, fixed itoxf, fixed itoyf, ! const gx_device_color *pdevc, gs_state *pgs) { int ix = fixed2int_var(ixf); int iy = fixed2int_var(iyf); *************** *** 372,375 **** --- 388,392 ---- int itoy = fixed2int_var(itoyf); gx_device *dev; + gp_check_interrupts(); if ( itoy == iy ) /* horizontal line */ { return (ix <= itox ? *************** *** 393,397 **** fixed tf; #define fswap(a, b) tf = a, a = b, b = tf - #define half float2fixed(0.5) if ( (w < 0 ? -w : w) <= (h < 0 ? -h : h) ) { if ( h < 0 ) --- 410,413 ---- *************** *** 398,403 **** fswap(ixf, itoxf), fswap(iyf, itoyf), h = -h; ! return gz_fill_trapezoid_fixed(ixf - half, fixed_1, iyf, ! itoxf - half, fixed_1, h, 0, pdevc, pgs); } --- 414,419 ---- fswap(ixf, itoxf), fswap(iyf, itoyf), h = -h; ! return gz_fill_trapezoid_fixed(ixf - fixed_half, fixed_1, iyf, ! itoxf - fixed_half, fixed_1, h, 0, pdevc, pgs); } *************** *** 406,414 **** fswap(ixf, itoxf), fswap(iyf, itoyf), w = -w; ! return gz_fill_trapezoid_fixed(iyf - half, fixed_1, ixf, ! itoyf - half, fixed_1, w, 1, pdevc, pgs); } - #undef half #undef fswap } --- 422,429 ---- fswap(ixf, itoxf), fswap(iyf, itoyf), w = -w; ! return gz_fill_trapezoid_fixed(iyf - fixed_half, fixed_1, ixf, ! itoyf - fixed_half, fixed_1, w, 1, pdevc, pgs); } #undef fswap } diff -rc2N gs241/gxfill.c gs25/gxfill.c *** gs241/gxfill.c Thu Apr 9 17:53:58 1992 --- gs25/gxfill.c Mon Jun 22 17:00:10 1992 *************** *** 1,3 **** ! /* Copyright (C) 1989, 1990, 1991 Aladdin Enterprises. All rights reserved. Distributed by Free Software Foundation, Inc. --- 1,3 ---- ! /* Copyright (C) 1989, 1992 Aladdin Enterprises. All rights reserved. Distributed by Free Software Foundation, Inc. *************** *** 40,44 **** gs_fixed_point start; /* x,y where line starts */ gs_fixed_point end; /* x,y where line ends */ ! #define al_dx(alp) ((alp)->end.x - (alp)->start.x) #define al_dy(alp) ((alp)->end.y - (alp)->start.y) fixed y_fast_max; /* can do x_at_y in fixed point */ --- 40,45 ---- gs_fixed_point start; /* x,y where line starts */ gs_fixed_point end; /* x,y where line ends */ ! fixed dx; /* end.x - start.x */ ! #define al_dx(alp) ((alp)->dx) #define al_dy(alp) ((alp)->end.y - (alp)->start.y) fixed y_fast_max; /* can do x_at_y in fixed point */ *************** *** 45,50 **** /* if y <= y_fast_max */ #define set_al_points(alp, startp, endp)\ ! (alp)->y_fast_max = max_fixed / (((endp).x > (startp).x ?\ ! (endp).x - (startp).x : (startp).x - (endp).x) | 1) + (startp).y,\ (alp)->start = startp, (alp)->end = endp #define al_x_at_y(alp, yv)\ --- 46,52 ---- /* if y <= y_fast_max */ #define set_al_points(alp, startp, endp)\ ! (alp)->dx = (endp).x - (startp).x,\ ! (alp)->y_fast_max = max_fixed /\ ! (((alp)->dx >= 0 ? (alp)->dx : -(alp)->dx) | 1) + (startp).y,\ (alp)->start = startp, (alp)->end = endp #define al_x_at_y(alp, yv)\ *************** *** 57,61 **** fixed x_current; /* current x position */ fixed x_next; /* x position at end of band */ ! segment *pseg; /* endpoint of this line */ int direction; /* direction of line segment */ #define dir_up 1 --- 59,63 ---- fixed x_current; /* current x position */ fixed x_next; /* x position at end of band */ ! const segment *pseg; /* endpoint of this line */ int direction; /* direction of line segment */ #define dir_up 1 *************** *** 138,146 **** private void free_line_list(P1(ll_ptr)); private int add_y_list(P2(gx_path *, ll_ptr)); ! private int add_y_line(P4(segment *, segment *, int, ll_ptr)); ! private int fill_loop(P5(gx_device_color *, int, ll_ptr, gs_state *, fixed)); private void insert_x_new(P2(active_line *, ll_ptr)); ! private void update_x_list(P2(active_line *, fixed)); /* Statistics */ --- 140,148 ---- private void free_line_list(P1(ll_ptr)); private int add_y_list(P2(gx_path *, ll_ptr)); ! private int add_y_line(P4(const segment *, const segment *, int, ll_ptr)); ! private int fill_loop(P5(const gx_device_color *, int, ll_ptr, gs_state *, fixed)); private void insert_x_new(P2(active_line *, ll_ptr)); ! private int update_x_list(P2(active_line *, fixed)); /* Statistics */ *************** *** 171,175 **** gx_fill_path(gx_path *ppath, gx_device_color *pdevc, gs_state *pgs, int rule, fixed adjust) ! { gx_clip_path *pcpath = pgs->clip_path; gs_fixed_rect cbox; gx_path *pfpath; --- 173,177 ---- gx_fill_path(gx_path *ppath, gx_device_color *pdevc, gs_state *pgs, int rule, fixed adjust) ! { const gx_clip_path *pcpath = pgs->clip_path; gs_fixed_rect cbox; gx_path *pfpath; *************** *** 187,191 **** pfpath = ppath; else ! { if ( (code = gx_path_flatten(ppath, &ffpath, pgs->flatness)) < 0 ) return code; pfpath = &ffpath; } --- 189,193 ---- pfpath = ppath; else ! { if ( (code = gx_path_flatten(ppath, &ffpath, pgs->flatness, (int)pgs->in_cachedevice)) < 0 ) return code; pfpath = &ffpath; } *************** *** 382,386 **** /* pending list if appropriate. */ private int ! add_y_line(segment *prev_lp, segment *lp, int dir, ll_ptr ll) { gs_fixed_point this, prev; register active_line *alp = ll->next_active; --- 384,388 ---- /* pending list if appropriate. */ private int ! add_y_line(const segment *prev_lp, const segment *lp, int dir, ll_ptr ll) { gs_fixed_point this, prev; register active_line *alp = ll->next_active; *************** *** 447,451 **** /* x_list as needed. */ private int ! fill_loop(gx_device_color *pdevc, int rule, ll_ptr ll, gs_state *pgs, fixed adjust) { fixed adj2 = adjust << 1; --- 449,453 ---- /* x_list as needed. */ private int ! fill_loop(const gx_device_color *pdevc, int rule, ll_ptr ll, gs_state *pgs, fixed adjust) { fixed adj2 = adjust << 1; *************** *** 453,456 **** --- 455,459 ---- gs_fixed_point pmax; fixed y; + int code; if ( yll == 0 ) return 0; /* empty list */ pmax = ll->box.q; *************** *** 487,491 **** #ifdef DEBUG if ( gs_debug['F'] ) ! { dprintf2("[f]before loop: y=%f y1=%f:\n", fixed2float(y), fixed2float(y1)); print_line_list(ll->x_list); --- 490,494 ---- #ifdef DEBUG if ( gs_debug['F'] ) ! { dprintf2("[F]before loop: y=%f y1=%f:\n", fixed2float(y), fixed2float(y1)); print_line_list(ll->x_list); *************** *** 519,528 **** /* Y value using only local information. */ fixed dy = y1 - y, y_new; ! #ifdef DEBUG ! if ( gs_debug['f'] || gs_debug['F'] ) ! dprintf3("[f]cross: dy=%g, dx_old=%g, dx_new=%g\n", fixed2float(dy), fixed2float(dx_old), fixed2float(dx_den - dx_old)); - #endif /* Do the computation in single precision */ /* if the values are small enough. */ --- 522,528 ---- /* Y value using only local information. */ fixed dy = y1 - y, y_new; ! if_debug3('f', "[f]cross: dy=%g, dx_old=%g, dx_new=%g\n", fixed2float(dy), fixed2float(dx_old), fixed2float(dx_den - dx_old)); /* Do the computation in single precision */ /* if the values are small enough. */ *************** *** 535,544 **** /* very accurate, but it does have to be */ /* greater than y and less than y1. */ ! #ifdef DEBUG ! if ( gs_debug['f'] || gs_debug['F'] ) ! dprintf3("[f]cross y=%g, y_new=%g, y1=%g\n", fixed2float(y), fixed2float(y_new), fixed2float(y1)); - #endif stopx = alp; if ( y_new <= y ) y_new = y + 1; --- 535,541 ---- /* very accurate, but it does have to be */ /* greater than y and less than y1. */ ! if_debug3('f', "[f]cross y=%g, y_new=%g, y1=%g\n", fixed2float(y), fixed2float(y_new), fixed2float(y1)); stopx = alp; if ( y_new <= y ) y_new = y + 1; *************** *** 557,561 **** #ifdef DEBUG if ( gs_debug['F'] ) ! { dprintf1("[f]after loop: y1=%f\n", fixed2float(y1)); print_line_list(ll->x_list); } --- 554,558 ---- #ifdef DEBUG if ( gs_debug['F'] ) ! { dprintf1("[F]after loop: y1=%f\n", fixed2float(y1)); print_line_list(ll->x_list); } *************** *** 586,590 **** { fixed wbot = xbot - xlbot + adj2; fixed wtop = xtop - xltop + adj2; - int code; stat(n_band_fill); /* If lines are temporarily out of */ --- 583,586 ---- *************** *** 611,615 **** } } ! update_x_list(ll->x_list, y1); y = y1; } --- 607,612 ---- } } ! code = update_x_list(ll->x_list, y1); ! if ( code < 0 ) return code; y = y1; } *************** *** 637,641 **** /* If any lines are out of order, re-sort them now. */ /* Also drop any ended lines. */ ! private void update_x_list(active_line *x_first, fixed y1) { fixed x; --- 634,638 ---- /* If any lines are out of order, re-sort them now. */ /* Also drop any ended lines. */ ! private int update_x_list(active_line *x_first, fixed y1) { fixed x; *************** *** 645,658 **** { fixed nx = alp->x_current = alp->x_next; nlp = alp->next; ! #ifdef DEBUG ! if ( gs_debug['f'] || gs_debug['F'] ) ! dprintf4("[f]check %lx,x=%g %lx,x=%g\n", ! (ulong)alp->prev, fixed2float(x), ! (ulong)alp, fixed2float(nx)); ! #endif if ( alp->end.y == y1 ) { /* Handle a line segment that just ended. */ ! segment *pseg = alp->pseg; ! segment *next; gs_fixed_point npt; /* --- 642,652 ---- { fixed nx = alp->x_current = alp->x_next; nlp = alp->next; ! if_debug4('f', "[f]check %lx,x=%g %lx,x=%g\n", ! (ulong)alp->prev, fixed2float(x), ! (ulong)alp, fixed2float(nx)); if ( alp->end.y == y1 ) { /* Handle a line segment that just ended. */ ! const segment *pseg = alp->pseg; ! const segment *next; gs_fixed_point npt; /* *************** *** 674,683 **** ); npt.y = next->pt.y; ! #ifdef DEBUG ! if ( gs_debug['F'] ) ! dprintf5("[f]ended %lx: pseg=%lx y=%f next=%lx npt.y=%f\n", (ulong)alp, (ulong)pseg, fixed2float(pseg->pt.y), (ulong)next, fixed2float(npt.y)); - #endif if ( npt.y <= pseg->pt.y ) { /* End of a line sequence */ --- 668,674 ---- ); npt.y = next->pt.y; ! if_debug5('F', "[F]ended %lx: pseg=%lx y=%f next=%lx npt.y=%f\n", (ulong)alp, (ulong)pseg, fixed2float(pseg->pt.y), (ulong)next, fixed2float(npt.y)); if ( npt.y <= pseg->pt.y ) { /* End of a line sequence */ *************** *** 684,691 **** alp->prev->next = nlp; if ( nlp ) nlp->prev = alp->prev; ! #ifdef DEBUG ! if ( gs_debug['F'] ) ! dprintf1("[f]drop %lx\n", (ulong)alp); ! #endif continue; } --- 675,679 ---- alp->prev->next = nlp; if ( nlp ) nlp->prev = alp->prev; ! if_debug1('F', "[F]drop %lx\n", (ulong)alp); continue; } *************** *** 704,713 **** if ( next ) next->prev = prev; while ( !x_precedes(prev, alp, nx) ) ! { ! #ifdef DEBUG ! if ( gs_debug['f'] || gs_debug['F'] ) ! dprintf2("[f]swap %lx,%lx\n", (ulong)alp, (ulong)prev); - #endif next = prev, prev = prev->prev; } --- 692,697 ---- if ( next ) next->prev = prev; while ( !x_precedes(prev, alp, nx) ) ! { if_debug2('f', "[f]swap %lx,%lx\n", (ulong)alp, (ulong)prev); next = prev, prev = prev->prev; } *************** *** 729,734 **** print_active_line(" 1:", alp); print_active_line(" 2:", alp->next); ! gs_exit(1); } #endif } --- 713,719 ---- print_active_line(" 1:", alp); print_active_line(" 2:", alp->next); ! return_error(gs_error_Fatal); } #endif + return 0; } diff -rc2N gs241/gxfixed.h gs25/gxfixed.h *** gs241/gxfixed.h Mon Mar 16 17:07:02 1992 --- gs25/gxfixed.h Wed May 13 18:06:32 1992 *************** *** 55,58 **** --- 55,59 ---- #define fixed_0 int2fixed(0) #define fixed_1 int2fixed(1) + #define fixed_half (fixed_1 >> 1) /* * On 16-bit systems, we can convert fixed variables to ints more efficiently diff -rc2N gs241/gxfont.h gs25/gxfont.h *** gs241/gxfont.h Sat Mar 21 02:30:08 1992 --- gs25/gxfont.h Fri Jul 10 03:31:46 1992 *************** *** 79,92 **** /* This is the type-specific information for a type 1 (encrypted) gs_font. */ ! #define zone_table(tname, size)\ struct {\ int count;\ ! int data[(size)*2];\ ! } tname ! #define stem_table(tname, size)\ struct {\ int count;\ float data[size];\ ! } tname typedef struct gs_type1_data_s gs_type1_data; struct gs_type1_data_s { --- 79,94 ---- /* This is the type-specific information for a type 1 (encrypted) gs_font. */ ! /* The zone_table data should be ints, according to the Adobe specification, */ ! /* but some fonts have arbitrary floats here. */ ! #define zone_table(size)\ struct {\ int count;\ ! float data[(size)*2];\ ! } ! #define stem_table(size)\ struct {\ int count;\ float data[size];\ ! } typedef struct gs_type1_data_s gs_type1_data; struct gs_type1_data_s { *************** *** 93,122 **** int PaintType; /* PaintType */ int (*subr_proc)(P3(gs_type1_data *pdata, ! int index, byte **pcharstring)); int (*pop_proc)(P2(gs_type1_data *, fixed *)); char *proc_data; /* data for subr_proc */ int lenIV; /* # of leading garbage bytes */ ! /* The following hint information is not used yet. */ ! /* See chapter 5 of the "Adobe Type 1 Font Format" book. */ int BlueFuzz; float BlueScale; ! int BlueShift; #define max_BlueValues 7 ! zone_table(BlueValues, max_BlueValues); float ExpansionFactor; int ForceBold; #define max_FamilyBlues 7 ! zone_table(FamilyBlues, max_FamilyBlues); #define max_FamilyOtherBlues 5 ! zone_table(FamilyOtherBlues, max_FamilyOtherBlues); int LanguageGroup; #define max_OtherBlues 5 ! zone_table(OtherBlues, max_OtherBlues); int RndStemUp; ! stem_table(StdHW, 1); ! stem_table(StdVW, 1); #define max_StemSnap 12 ! stem_table(StemSnapH, max_StemSnap); ! stem_table(StemSnapV, max_StemSnap); }; #define gs_type1_data_s_DEFINED --- 95,124 ---- int PaintType; /* PaintType */ int (*subr_proc)(P3(gs_type1_data *pdata, ! int index, const byte **pcharstring)); int (*pop_proc)(P2(gs_type1_data *, fixed *)); char *proc_data; /* data for subr_proc */ int lenIV; /* # of leading garbage bytes */ ! /* For a description of the following hint information, */ ! /* see chapter 5 of the "Adobe Type 1 Font Format" book. */ int BlueFuzz; float BlueScale; ! float BlueShift; #define max_BlueValues 7 ! zone_table(max_BlueValues) BlueValues; float ExpansionFactor; int ForceBold; #define max_FamilyBlues 7 ! zone_table(max_FamilyBlues) FamilyBlues; #define max_FamilyOtherBlues 5 ! zone_table(max_FamilyOtherBlues) FamilyOtherBlues; int LanguageGroup; #define max_OtherBlues 5 ! zone_table(max_OtherBlues) OtherBlues; int RndStemUp; ! stem_table(1) StdHW; ! stem_table(1) StdVW; #define max_StemSnap 12 ! stem_table(max_StemSnap) StemSnapH; ! stem_table(max_StemSnap) StemSnapV; }; #define gs_type1_data_s_DEFINED diff -rc2N gs241/gxhint1.c gs25/gxhint1.c *** gs241/gxhint1.c --- gs25/gxhint1.c Mon Jul 20 17:04:50 1992 *************** *** 0 **** --- 1,473 ---- + /* Copyright (C) 1990, 1992 Aladdin Enterprises. All rights reserved. + Distributed by Free Software Foundation, Inc. + + This file is part of Ghostscript. + + Ghostscript is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY. No author or distributor accepts responsibility + to anyone for the consequences of using it or for whether it serves any + particular purpose or works at all, unless he says so in writing. Refer + to the Ghostscript General Public License for full details. + + Everyone is granted permission to copy, modify and redistribute + Ghostscript, but only under the conditions described in the Ghostscript + General Public License. A copy of this license is supposed to have been + given to you along with Ghostscript so you can know your rights and + responsibilities. It should be in a file named COPYING. Among other + things, the copyright notice and this notice must be preserved on all + copies. */ + + /* gxhint1.c */ + /* Adobe Type 1 font hint routines */ + #include "gx.h" + #include "gserrors.h" + #include "gxarith.h" + #include "gxfixed.h" + #include "gxmatrix.h" + #include "gzstate.h" + #include "gzdevice.h" /* for gxchar */ + #include "gxdevmem.h" /* ditto */ + #include "gxchar.h" + #include "gxfont.h" + #include "gxtype1.h" + + /* Define the tolerance for testing whether a point is in a zone, */ + /* in device pixels. (Maybe this should be variable??) */ + #define stem_tolerance float2fixed(0.05) + + /* ------ Initialization ------ */ + + typedef zone_table(1) a_zone_table; + private alignment_zone *near + compute_zones(P6(const gs_matrix_fixed *, const font_hints *, + const a_zone_table *, const a_zone_table *, alignment_zone *, int)); + private void near + transform_zone(P4(const gs_matrix_fixed *, const font_hints *, + const float *, alignment_zone *)); + + /* Compute the font-level hints from the font and the matrix. */ + /* We should cache this with the font/matrix pair.... */ + void + compute_font_hints(font_hints *pfh, const gs_matrix_fixed *pmat, + const gs_type1_data *pdata) + { int h_count = 0, v_count = 0; + alignment_zone *zp = &pfh->a_zones[0]; + /* Figure out which hints, if any, to use, */ + /* and the orientation of the axes. */ + pfh->axes_swapped = pfh->x_inverted = pfh->y_inverted = 0; + pfh->use_x_hints = pfh->use_y_hints = 0; + if ( is_fzero(pmat->xy) ) + pfh->y_inverted = is_fneg(pmat->yy), + pfh->use_y_hints = 1; + else if ( is_fzero(pmat->xx) ) + pfh->y_inverted = is_fneg(pmat->xy), + pfh->axes_swapped = 1, + pfh->use_y_hints = 1; + if ( is_fzero(pmat->yx) ) + pfh->x_inverted = is_fneg(pmat->xx), + pfh->use_x_hints = 1; + else if ( is_fzero(pmat->yy) ) + pfh->x_inverted = is_fneg(pmat->yx), + pfh->axes_swapped = 1, + pfh->use_x_hints = 1; + if_debug6('1', "[1]ctm=[%g %g %g %g %g %g]\n", + pmat->xx, pmat->xy, pmat->yx, pmat->yy, + pmat->tx, pmat->ty); + if_debug5('1', "[1]swapped=%d, x/y_hints=%d,%d, x/y_inverted=%d,%d\n", + pfh->axes_swapped, pfh->use_x_hints, pfh->use_y_hints, + pfh->x_inverted, pfh->y_inverted); + /* Transform the actual hints. */ + if ( pfh->use_x_hints ) + { gs_fixed_point hw; + fixed *hp = (pfh->axes_swapped ? &hw.y : &hw.x); + int i; + if ( pdata->StdHW.count ) + { gs_distance_transform2fixed(pmat, + (float)pdata->StdHW.data[0], 0.0, &hw); + pfh->snap_h.data[0] = any_abs(*hp); + if_debug1('1', "[1]snap_h[0]=%g\n", + fixed2float(pfh->snap_h.data[0])); + h_count = 1; + } + for ( i = 0; i < pdata->StemSnapH.count; i++ ) + { gs_distance_transform2fixed(pmat, + (float)pdata->StemSnapH.data[i], 0.0, &hw); + pfh->snap_h.data[h_count++] = any_abs(*hp); + if_debug2('1', "[1]snap_h[%d]=%g\n", h_count - 1, + fixed2float(pfh->snap_h.data[h_count - 1])); + } + } + if ( pfh->use_y_hints ) + { gs_fixed_point vw; + fixed *vp = (pfh->axes_swapped ? &vw.x : &vw.y); + int i; + /* Convert blue parameters to device pixels. */ + gs_distance_transform2fixed(pmat, 0.0, + (float)pdata->BlueFuzz, &vw); + pfh->blue_fuzz = any_abs(*vp); + gs_distance_transform2fixed(pmat, 0.0, 1.0, &vw); + pfh->suppress_overshoot = any_abs(*vp) < pdata->BlueScale; + gs_distance_transform2fixed(pmat, 0.0, pdata->BlueShift, &vw); + pfh->blue_shift = any_abs(*vp); + /* Tweak up blue_shift if it is less than half a pixel. */ + /* See the discussion of BlueShift in section 5.7 of */ + /* "Adobe Type 1 Font Format." */ + if ( pfh->blue_shift < fixed_half ) + pfh->blue_shift = fixed_half; + if_debug5('1', "[1]blue_fuzz=%d->%g, blue_shift=%g->%g, sup_ov=%d\n", + pdata->BlueFuzz, fixed2float(pfh->blue_fuzz), + pdata->BlueShift, fixed2float(pfh->blue_shift), + pfh->suppress_overshoot); + zp = compute_zones(pmat, pfh, + (const a_zone_table *)&pdata->BlueValues, + (const a_zone_table *)&pdata->FamilyBlues, + zp, 1); + zp = compute_zones(pmat, pfh, + (const a_zone_table *)&pdata->OtherBlues, + (const a_zone_table *)&pdata->FamilyOtherBlues, + zp, max_OtherBlues); + if ( pdata->StdVW.count ) + { gs_distance_transform2fixed(pmat, 0.0, + (float)pdata->StdVW.data[0], &vw); + pfh->snap_v.data[0] = any_abs(*vp); + if_debug1('1', "[1]snap_v[0]=%g\n", + fixed2float(pfh->snap_v.data[0])); + v_count = 1; + } + for ( i = 0; i < pdata->StemSnapV.count; i++ ) + { gs_distance_transform2fixed(pmat, 0.0, + (float)pdata->StemSnapV.data[i], &vw); + pfh->snap_v.data[v_count++] = any_abs(*vp); + if_debug2('1', "[1]snap_v[%d]=%g\n", v_count - 1, + fixed2float(pfh->snap_v.data[v_count - 1])); + } + } + pfh->snap_h.count = h_count; + pfh->snap_v.count = v_count; + pfh->a_zone_count = zp - &pfh->a_zones[0]; + } + + /* Compute the alignment zones for one set of 'blue' values. */ + private alignment_zone *near + compute_zones(const gs_matrix_fixed *pmat, const font_hints *pfh, + const a_zone_table *blues, const a_zone_table *family_blues, + alignment_zone *zp, int bottom_count) + { int i; + fixed fuzz = pfh->blue_fuzz; + int inverted = + (pfh->axes_swapped ? pfh->x_inverted : pfh->y_inverted); + for ( i = 0; i < blues->count; i += 2, zp++ ) + { const float *vp = &blues->data[i]; + zp->is_top_zone = i >> 1 >= bottom_count; + transform_zone(pmat, pfh, vp, zp); + if_debug5('1', "[1]blues[%d]=%g,%g -> %g,%g\n", + i >> 1, vp[0], vp[1], + fixed2float(zp->v0), fixed2float(zp->v1)); + if ( i < family_blues->count ) + { /* Check whether family blues should supersede. */ + alignment_zone fz; + const float *fvp = &family_blues->data[i]; + fixed diff; + transform_zone(pmat, pfh, fvp, &fz); + if_debug5('1', "[1]f_blues[%d]=%g,%g -> %g,%g\n", + i >> 1, fvp[0], fvp[1], + fixed2float(fz.v0), fixed2float(fz.v1)); + diff = (zp->v1 - zp->v0) - (fz.v1 - fz.v0); + if ( diff > -fixed_1 && diff < fixed_1 ) + zp->v0 = fz.v0, zp->v1 = fz.v1; + } + /* Compute the flat position, and add the fuzz. */ + if ( (inverted ? zp->is_top_zone : !zp->is_top_zone) ) + zp->flat = zp->v1, zp->v0 -= fuzz; + else + zp->flat = zp->v0, zp->v1 += fuzz; + } + return zp; + } + + /* Transform a single alignment zone to device coordinates, */ + /* taking axis swapping into account. */ + private void near + transform_zone(const gs_matrix_fixed *pmat, const font_hints *pfh, + const float *vp, alignment_zone *zp) + { gs_fixed_point p0, p1; + fixed v0, v1; + gs_point_transform2fixed(pmat, 0.0, vp[0], &p0); + gs_point_transform2fixed(pmat, 0.0, vp[1], &p1); + if ( pfh->axes_swapped ) v0 = p0.x, v1 = p1.x; + else v0 = p0.y, v1 = p1.y; + if ( v0 <= v1 ) zp->v0 = v0, zp->v1 = v1; + else zp->v0 = v1, zp->v1 = v0; + } + + /* Reset the stem hints. */ + void + reset_stem_hints(register gs_type1_state *pis) + { pis->hstem_hints.count = 0; + pis->hstem_hints.current = &pis->hstem_hints.data[0]; + pis->vstem_hints.count = 0; + pis->vstem_hints.current = &pis->vstem_hints.data[0]; + } + + /* ------ Add hints ------ */ + + private stem_hint *near type1_stem(P3(stem_hint_table *, fixed, fixed)); + private fixed near find_snap(P2(fixed, const stem_snap_table *)); + private alignment_zone *near + find_zone(P3(gs_type1_state *, fixed, fixed)); + + #define c_fixed(d, c) m_fixed(fixed2int_var(d), c, pis->fc) + + /* Add a horizontal stem hint. */ + void + type1_hstem(register gs_type1_state *pis, fixed y, fixed dy) + { stem_hint *psh; + alignment_zone *pz; + fixed v, dv, adj_dv; + fixed vtop, vbot; + fixed center, diff_v, diff2_dv; + if ( !pis->fh.use_y_hints ) return; + y += pis->lsb.y; + if ( pis->fh.axes_swapped ) + v = pis->vs_offset.x + c_fixed(y, pis->fc.yx) + + pis->pgs->ctm.tx_fixed, + dv = c_fixed(dy, pis->fc.yx); + else + v = pis->vs_offset.y + c_fixed(y, pis->fc.yy) + + pis->pgs->ctm.ty_fixed, + dv = c_fixed(dy, pis->fc.yy); + if ( dy < 0 ) + vbot = v + dv, vtop = v; + else + vbot = v, vtop = v + dv; + if ( dv < 0 ) v += dv, dv = -dv; + psh = type1_stem(&pis->hstem_hints, v, dv); + if ( psh == 0 ) return; + adj_dv = find_snap(dv, &pis->fh.snap_h); + pz = find_zone(pis, vbot, vtop); + if ( pz != 0 ) + { /* Use the alignment zone to align the outer stem edge. */ + int inverted = + (pis->fh.axes_swapped ? pis->fh.x_inverted : pis->fh.y_inverted); + int adjust_v1 = + (inverted ? !pz->is_top_zone : pz->is_top_zone); + fixed flat_v = pz->flat; + fixed overshoot = + (pz->is_top_zone ? vtop - flat_v : flat_v - vbot); + fixed pos_over = + (inverted ? -overshoot : overshoot); + fixed ddv = adj_dv - dv; + fixed shift = fixed_rounded(flat_v) - flat_v; + if ( pos_over > 0 ) + { if ( pos_over < pis->fh.blue_shift || pis->fh.suppress_overshoot ) + { /* Character is small, suppress overshoot. */ + if_debug0('1', "[1]suppress overshoot\n"); + if ( pz->is_top_zone ) + shift -= overshoot; + else + shift += overshoot; + } + else if ( pos_over < fixed_1 ) + { /* Enforce overshoot. */ + if_debug0('1', "[1]enforce overshoot\n"); + if ( overshoot < 0 ) + overshoot = -fixed_1 - overshoot; + else + overshoot = fixed_1 - overshoot; + if ( pz->is_top_zone ) + shift += overshoot; + else + shift -= overshoot; + } + } + if ( adjust_v1 ) + psh->dv1 = shift, psh->dv0 = shift - ddv; + else + psh->dv0 = shift, psh->dv1 = shift + ddv; + if_debug4('1', "[1]flat_v = %g, overshoot = %g, dv=%g,%g\n", + fixed2float(flat_v), fixed2float(overshoot), + fixed2float(psh->dv0), fixed2float(psh->dv1)); + return; + } + /* Align the stem so its edges fall on pixel boundaries, */ + /* moving the center as little as possible. */ + center = v + arith_rshift_1(dv); + if ( adj_dv & fixed_1 ) + { /* Odd width, align center on half-pixel. */ + center += fixed_half; + } + diff_v = fixed_rounded(center) - center; + diff2_dv = arith_rshift_1(adj_dv - dv); + psh->dv0 = diff_v - diff2_dv; + psh->dv1 = diff_v + diff2_dv; + if_debug6('1', "[1]hstem %g,%g -> %g,%g ; d = %g,%g\n", + fixed2float(y), fixed2float(dy), + fixed2float(v), fixed2float(dv), + fixed2float(psh->dv0), fixed2float(psh->dv1)); + } + + /* Add a vertical stem hint. */ + void + type1_vstem(register gs_type1_state *pis, fixed x, fixed dx) + { stem_hint *psh; + fixed v, dv, adj_dv; + fixed center, diff_v, diff2_dv; + if ( !pis->fh.use_x_hints ) return; + x += pis->lsb.x; + if ( pis->fh.axes_swapped ) + v = pis->vs_offset.y + c_fixed(x, pis->fc.xy) + + pis->pgs->ctm.ty_fixed, + dv = c_fixed(dx, pis->fc.xy); + else + v = pis->vs_offset.x + c_fixed(x, pis->fc.xx) + + pis->pgs->ctm.tx_fixed, + dv = c_fixed(dx, pis->fc.xx); + if ( dv < 0 ) v += dv, dv = -dv; + psh = type1_stem(&pis->vstem_hints, v, dv); + if ( psh == 0 ) return; + adj_dv = find_snap(dv, &pis->fh.snap_v); + if ( pis->pdata->ForceBold && adj_dv < fixed_1 ) + adj_dv = fixed_1; + /* Align the stem so its edges fall on pixel boundaries, */ + /* moving the center as little as possible. */ + center = v + arith_rshift_1(dv); + if ( adj_dv & fixed_1 ) + { /* Odd width, align center on half-pixel. */ + center += fixed_half; + } + diff_v = fixed_rounded(center) - center; + diff2_dv = arith_rshift_1(adj_dv - dv); + psh->dv0 = diff_v - diff2_dv; + psh->dv1 = diff_v + diff2_dv; + if_debug6('1', "[1]vstem %g,%g -> %g,%g ; d = %g,%g\n", + fixed2float(x), fixed2float(dx), + fixed2float(v), fixed2float(dv), + fixed2float(psh->dv0), fixed2float(psh->dv1)); + } + + /* Add a stem hint, keeping the table sorted. */ + /* Return the stem hint pointer, or 0 if the table is full. */ + private stem_hint *near + type1_stem(stem_hint_table *psht, fixed v0, fixed d) + { stem_hint *bot = &psht->data[0]; + stem_hint *top = bot + psht->count; + if ( psht->count >= max_stems ) return 0; + while ( top > bot && v0 < top[-1].v0 ) + { *top = top[-1]; + top--; + } + /* Add a little fuzz for insideness testing. */ + top->v0 = v0 - stem_tolerance; + top->v1 = v0 + d + stem_tolerance; + psht->count++; + return top; + } + + /* Compute the adjusted width of a stem. */ + private fixed near + find_snap(fixed dv, const stem_snap_table *psst) + { fixed best = fixed_1 * 2; + fixed adj_dv; + int i; + for ( i = 0; i < psst->count; i++ ) + { fixed diff = psst->data[i] - dv; + if ( any_abs(diff) < any_abs(best) ) + { if_debug3('1', "[1]snap %g to [%d]%g\n", + fixed2float(dv), i, + fixed2float(psst->data[i])); + best = diff; + } + } + adj_dv = fixed_rounded(any_abs(best) <= fixed_1 ? dv + best : dv); + if ( adj_dv == 0 ) adj_dv = fixed_1; + if_debug2('1', "[1]snap %g to %g\n", + fixed2float(dv), fixed2float(adj_dv)); + return adj_dv; + } + + /* Find the applicable alignment zone for a stem, if any. */ + /* vbot and vtop are the bottom and top of the stem, */ + /* but without interchanging if the y axis is inverted. */ + private alignment_zone *near + find_zone(gs_type1_state *pis, fixed vbot, fixed vtop) + { alignment_zone *pz; + for ( pz = &pis->fh.a_zones[pis->fh.a_zone_count]; --pz >= &pis->fh.a_zones[0]; ) + { fixed v = (pz->is_top_zone ? vtop : vbot); + if ( v >= pz->v0 && v <= pz->v1 ) + { if_debug2('1', "[1]stem crosses %s-zone %d\n", + (pz->is_top_zone ? "top" : "bottom"), + (int)(pz - &pis->fh.a_zones[0])); + return pz; + } + } + return 0; + } + + /* ------ Apply hints ------ */ + + private stem_hint *near + search_hints(P2(stem_hint_table *, fixed)); + + /* Adjust a point according to the relevant hints. */ + /* x and y are the current point in device space after moving; */ + /* dx and dy are the delta components in character space. */ + void + find_stem_hints(gs_type1_state *pis, fixed x, fixed y, + fixed dx, fixed dy, gs_fixed_point *ppt) + { ppt->x = x, ppt->y = y; + if ( pis->in_dotsection ) return; + /* Note that if use_x/y_hints is false, */ + /* no entries ever get made in the stem hint tables, */ + /* so we don't have to check those flags here. */ + /* Check the vertical stem hints. */ + if ( pis->vstem_hints.count ) + { fixed *pv = (pis->fh.axes_swapped ? &ppt->y : &ppt->x); + stem_hint *ph = search_hints(&pis->vstem_hints, *pv); + if ( ph != 0 ) + { /* Decide which side of the stem we are on. */ + /* If we're moving horizontally, just use the */ + /* x coordinate; otherwise, assume outside */ + /* edges move clockwise and inside edges move */ + /* counter-clockwise. (This algorithm was */ + /* taken from the IBM X11R5 rasterizer; I'm not */ + /* sure I believe it.) */ + #define adjust_stem(pv, dxy, ph, inverted)\ + *pv +=\ + ((/*dy == 0 ?*/ *pv < arith_rshift_1(ph->v0 +\ + ph->v1) /*: pis->fh.y_inverted ? dy < 0 : dy > 0*/) ?\ + ph->dv0 : ph->dv1) + if_debug2('1', "[1]use vstem %d: %g", + (int)(ph - &pis->vstem_hints.data[0]), + fixed2float(*pv)); + adjust_stem(pv, dy, ph, pis->fh.y_inverted); + if_debug1('1', " -> %g\n", fixed2float(*pv)); + } + } + /* Check the horizontal stem hints. */ + if ( pis->hstem_hints.count ) + { fixed *pv = (pis->fh.axes_swapped ? &ppt->x : &ppt->y); + stem_hint *ph = search_hints(&pis->hstem_hints, *pv); + if ( ph != 0 ) + { if_debug2('1', "[1]use hstem %d: %g", + (int)(ph - &pis->hstem_hints.data[0]), + fixed2float(*pv)); + adjust_stem(pv, dx, ph, pis->fh.x_inverted); + if_debug1('1', " -> %g\n", fixed2float(*pv)); + } + } + return; + #undef adjust_stem + } + + /* Search one hint table for an adjustment. */ + private stem_hint *near + search_hints(stem_hint_table *psht, fixed v) + { stem_hint *ph = psht->current; + if ( v >= ph->v0 && v <= ph->v1 ) return ph; + /* We don't bother with binary or even up/down search, */ + /* because there won't be very many hints. */ + for ( ph = &psht->data[psht->count]; --ph >= &psht->data[0]; ) + if ( v >= ph->v0 && v <= ph->v1 ) + return (psht->current = ph); + return 0; + } diff -rc2N gs241/gxht.c gs25/gxht.c *** gs241/gxht.c Thu Apr 16 18:14:10 1992 --- gs25/gxht.c Sat Jun 20 05:22:40 1992 *************** *** 1,3 **** ! /* Copyright (C) 1989, 1990, 1991 Aladdin Enterprises. All rights reserved. Distributed by Free Software Foundation, Inc. --- 1,3 ---- ! /* Copyright (C) 1989, 1992 Aladdin Enterprises. All rights reserved. Distributed by Free Software Foundation, Inc. *************** *** 93,97 **** # define b2(hi,lo) (lo<<8)+hi #endif ! private bit16 single_bits[16] = { b2(0x80,0), b2(0x40,0), b2(0x20,0), b2(0x10,0), b2(8,0), b2(4,0), b2(2,0), b2(1,0), --- 93,97 ---- # define b2(hi,lo) (lo<<8)+hi #endif ! private const bit16 single_bits[16] = { b2(0x80,0), b2(0x40,0), b2(0x20,0), b2(0x10,0), b2(8,0), b2(4,0), b2(2,0), b2(1,0), *************** *** 99,123 **** b2(0,8), b2(0,4), b2(0,2), b2(0,1) }; ! private bit16 mb1[1] = { b2(0xff,0xff) }; ! private bit16 mb2[2] = { b2(0xaa,0xaa), b2(0x55,0x55) }; ! private bit16 mb3[3] = { b2(0x92,0x49), b2(0x49,0x24), b2(0x24,0x92) }; ! private bit16 mb4[4] = { b2(0x88,0x88), b2(0x44,0x44), b2(0x22,0x22), b2(0x11,0x11) }; ! private bit16 mb5[5] = { b2(0x84,0x21), b2(0x42,0x10), b2(0x21,0x08), b2(0x10,0x84), b2(0x08,0x42) }; ! private bit16 mb6[6] = { b2(0x82,0x08), b2(0x41,0x04), b2(0x20,0x82), b2(0x10,0x41), b2(0x08,0x20), b2(0x04,0x10) }; ! private bit16 mb7[7] = { b2(0x81,0x02), b2(0x40,0x81), b2(0x20,0x40), b2(0x10,0x20), b2(0x08,0x10), b2(0x04,0x08), b2(0x02,0x04) }; ! private bit16 mb8[8] = { b2(0x80,0x80), b2(0x40,0x40), b2(0x20,0x20), b2(0x10,0x10), b2(0x08,0x08), b2(0x04,0x04), b2(0x02,0x02), b2(0x01,0x01) --- 99,123 ---- b2(0,8), b2(0,4), b2(0,2), b2(0,1) }; ! private const bit16 mb1[1] = { b2(0xff,0xff) }; ! private const bit16 mb2[2] = { b2(0xaa,0xaa), b2(0x55,0x55) }; ! private const bit16 mb3[3] = { b2(0x92,0x49), b2(0x49,0x24), b2(0x24,0x92) }; ! private const bit16 mb4[4] = { b2(0x88,0x88), b2(0x44,0x44), b2(0x22,0x22), b2(0x11,0x11) }; ! private const bit16 mb5[5] = { b2(0x84,0x21), b2(0x42,0x10), b2(0x21,0x08), b2(0x10,0x84), b2(0x08,0x42) }; ! private const bit16 mb6[6] = { b2(0x82,0x08), b2(0x41,0x04), b2(0x20,0x82), b2(0x10,0x41), b2(0x08,0x20), b2(0x04,0x10) }; ! private const bit16 mb7[7] = { b2(0x81,0x02), b2(0x40,0x81), b2(0x20,0x40), b2(0x10,0x20), b2(0x08,0x10), b2(0x04,0x08), b2(0x02,0x04) }; ! private const bit16 mb8[8] = { b2(0x80,0x80), b2(0x40,0x40), b2(0x20,0x20), b2(0x10,0x10), b2(0x08,0x08), b2(0x04,0x04), b2(0x02,0x02), b2(0x01,0x01) *************** *** 124,128 **** }; #undef b2 ! private bit16 *multi_bits[9] = { 0, mb1, mb2, mb3, mb4, mb5, mb6, mb7, mb8 }; --- 124,128 ---- }; #undef b2 ! private const bit16 *multi_bits[9] = { 0, mb1, mb2, mb3, mb4, mb5, mb6, mb7, mb8 }; *************** *** 168,175 **** /* Make the cache order current, and return whether */ /* there is room for all possible tiles in the cache. */ ! private void init_ht(P2(ht_cache *, halftone_params *)); int gx_check_tile_cache(gs_state *pgs) ! { halftone_params *pht = pgs->halftone; if ( cache.order != pht->order ) init_ht(&cache, pht); --- 168,175 ---- /* Make the cache order current, and return whether */ /* there is room for all possible tiles in the cache. */ ! private void init_ht(P2(ht_cache *, const halftone_params *)); int gx_check_tile_cache(gs_state *pgs) ! { const halftone_params *pht = pgs->halftone; if ( cache.order != pht->order ) init_ht(&cache, pht); *************** *** 195,205 **** /* Load the device color into the halftone cache if needed. */ ! private void render_ht(P4(bit_tile *, int, halftone_params *, gx_bitmap_id)); ! void gx_color_load(gx_device_color *pdevc, gs_state *pgs) { int level = pdevc->halftone_level; ! halftone_params *pht; bit_tile *bt; ! if ( level == 0 ) return; /* no halftone */ pht = pgs->halftone; if ( cache.order != pht->order ) --- 195,205 ---- /* Load the device color into the halftone cache if needed. */ ! private int render_ht(P4(bit_tile *, int, const halftone_params *, gx_bitmap_id)); ! int gx_color_load(gx_device_color *pdevc, gs_state *pgs) { int level = pdevc->halftone_level; ! const halftone_params *pht; bit_tile *bt; ! if ( level == 0 ) return 0; /* no halftone */ pht = pgs->halftone; if ( cache.order != pht->order ) *************** *** 207,212 **** bt = &cache.tiles[level / cache.levels_per_tile]; if ( bt->level != level ) ! render_ht(bt, level, pht, cache.base_id); pdevc->tile = &bt->tile; } --- 207,215 ---- bt = &cache.tiles[level / cache.levels_per_tile]; if ( bt->level != level ) ! { int code = render_ht(bt, level, pht, cache.base_id); ! if ( code < 0 ) return code; ! } pdevc->tile = &bt->tile; + return 0; } *************** *** 214,218 **** /* Cache as many different levels as will fit. */ private void ! init_ht(ht_cache *pcache, halftone_params *pht) { int width = pht->width; int height = pht->height; --- 217,221 ---- /* Cache as many different levels as will fit. */ private void ! init_ht(ht_cache *pcache, const halftone_params *pht) { int width = pht->width; int height = pht->height; *************** *** 232,236 **** if ( num_cached > size ) num_cached = size; if ( num_cached > max_cached_tiles ) num_cached = max_cached_tiles; ! if ( num_cached == size && num_cached <= max_cached_tiles / 2 ) { /* We can afford to replicate every tile vertically, */ /* which will reduce breakage when tiling. */ --- 235,241 ---- if ( num_cached > size ) num_cached = size; if ( num_cached > max_cached_tiles ) num_cached = max_cached_tiles; ! if ( num_cached == size && ! tile_bytes * num_cached <= max_ht_bits / 2 ! ) { /* We can afford to replicate every tile vertically, */ /* which will reduce breakage when tiling. */ *************** *** 264,270 **** * which correspond to black or white respectively. */ ! private void render_ht(bit_tile *pbt, int level /* [1..order_size-1] */, ! halftone_params *pht, gx_bitmap_id base_id) { ht_bit *order = pht->order; register ht_bit *p; --- 269,275 ---- * which correspond to black or white respectively. */ ! private int render_ht(bit_tile *pbt, int level /* [1..order_size-1] */, ! const halftone_params *pht, gx_bitmap_id base_id) { ht_bit *order = pht->order; register ht_bit *p; *************** *** 288,292 **** if ( level < 0 || level > pht->order_size || level == old_level ) { lprintf3("Error in render_ht: level=%d, old_level=%d, order_size=%d=n", level, old_level, pht->order_size); ! gs_exit(1); } #endif --- 293,297 ---- if ( level < 0 || level > pht->order_size || level == old_level ) { lprintf3("Error in render_ht: level=%d, old_level=%d, order_size=%d=n", level, old_level, pht->order_size); ! return_error(gs_error_Fatal); } #endif *************** *** 313,318 **** pht->width, pbt->tile.size.y, pht->height); while ( p < ptr ) ! { dprintf1(" %02x", *p++); ! if ( (p - bits) % wb == 0 ) dputc('\n'); } } --- 318,326 ---- pht->width, pbt->tile.size.y, pht->height); while ( p < ptr ) ! { dprintf8(" %d%d%d%d%d%d%d%d", ! *p >> 7, (*p >> 6) & 1, (*p >> 5) & 1, ! (*p >> 4) & 1, (*p >> 3) & 1, (*p >> 2) & 1, ! (*p >> 1) & 1, *p & 1); ! if ( (++p - bits) % wb == 0 ) dputc('\n'); } } *************** *** 334,336 **** --- 342,345 ---- while ( (h -= rh) != 0 ); } + return 0; } diff -rc2N gs241/gximage.h gs25/gximage.h *** gs241/gximage.h Thu Feb 13 02:53:52 1992 --- gs25/gximage.h Fri Aug 7 10:49:10 1992 *************** *** 27,31 **** /* so we have to do it with a macro instead: */ #define iunpack_proc_args\ ! P5(gs_image_enum *, byte *, byte *, uint, uint) #define irender_proc_args\ P4(gs_image_enum *, byte *, uint, int) --- 27,31 ---- /* so we have to do it with a macro instead: */ #define iunpack_proc_args\ ! P5(const gs_image_enum *, byte *, const byte *, uint, uint) #define irender_proc_args\ P4(gs_image_enum *, byte *, uint, int) *************** *** 32,35 **** --- 32,37 ---- /* Main state structure */ struct gs_image_enum_s { + /* We really want the map structure to be long-aligned, */ + /* so we choose shorter types for some flags. */ /* Following are set at structure initialization */ int width; *************** *** 46,51 **** gs_fixed_rect clip_box; /* pgs->clip_path.path->bbox, */ /* possibly translated */ - gs_int_rect ibox; /* integer version of clip_box, */ - /* only used for direct/buffered */ byte *buffer; /* for expanding to 8 bits/sample */ uint buffer_size; --- 48,51 ---- *************** *** 53,64 **** /* (per plane, if spp == 1 and */ /* spread > 1) */ ! int never_clip; /* true if entire image fits */ ! int skewed; /* true if image is skewed */ /* or rotated */ ! int slow_loop; /* true if !(skewed | non-rect clip */ ! /* | imagemask with a halftone) */ fixed adjust; /* adjustment when rendering */ /* characters */ ! ulong _ds *map4to32; /* expansion map for monobit images */ gx_device_clip clip_dev; /* clipping device (if needed) */ /* Following are updated dynamically */ --- 53,69 ---- /* (per plane, if spp == 1 and */ /* spread > 1) */ ! byte never_clip; /* true if entire image fits */ ! byte skewed; /* true if image is skewed */ /* or rotated */ ! byte slow_loop; /* true if !(skewed | */ ! /* imagemask with a halftone) */ ! byte _pad; fixed adjust; /* adjustment when rendering */ /* characters */ ! union { /* expansion and/or translation map */ ! ulong from4x1to32[16]; ! ushort from2x2to16[16]; ! byte to8[256]; ! } map; gx_device_clip clip_dev; /* clipping device (if needed) */ /* Following are updated dynamically */ diff -rc2N gs241/gxmatrix.h gs25/gxmatrix.h *** gs241/gxmatrix.h Tue Mar 24 03:25:08 1992 --- gs25/gxmatrix.h Sun May 24 04:20:38 1992 *************** *** 33,38 **** /* Coordinate transformations to fixed point */ ! int gs_point_transform2fixed(P4(gs_matrix_fixed *, floatp, floatp, gs_fixed_point *)), ! gs_distance_transform2fixed(P4(gs_matrix_fixed *, floatp, floatp, gs_fixed_point *)); /* Macro for testing whether matrix coefficients are zero, */ --- 33,38 ---- /* Coordinate transformations to fixed point */ ! int gs_point_transform2fixed(P4(const gs_matrix_fixed *, floatp, floatp, gs_fixed_point *)), ! gs_distance_transform2fixed(P4(const gs_matrix_fixed *, floatp, floatp, gs_fixed_point *)); /* Macro for testing whether matrix coefficients are zero, */ diff -rc2N gs241/gxop1.h gs25/gxop1.h *** gs241/gxop1.h Sun Mar 15 12:40:54 1992 --- gs25/gxop1.h Sat Apr 25 16:59:32 1992 *************** *** 28,32 **** fixed_coeff fc; fixed ctx, cty; /* character origin (device space) */ ! fixed px, py; /* current point (char space) */ } gs_op1_state; typedef gs_op1_state _ss *is_ptr; --- 28,32 ---- fixed_coeff fc; fixed ctx, cty; /* character origin (device space) */ ! fixed px, py; /* current point (device space) */ } gs_op1_state; typedef gs_op1_state _ss *is_ptr; diff -rc2N gs241/gxpath.c gs25/gxpath.c *** gs241/gxpath.c Mon Nov 25 12:30:46 1991 --- gs25/gxpath.c Mon Jul 13 16:30:00 1992 *************** *** 1,3 **** ! /* Copyright (C) 1989, 1990, 1991 Aladdin Enterprises. All rights reserved. Distributed by Free Software Foundation, Inc. --- 1,3 ---- ! /* Copyright (C) 1989, 1992 Aladdin Enterprises. All rights reserved. Distributed by Free Software Foundation, Inc. *************** *** 19,23 **** /* gxpath.c */ ! /* Private path routines for Ghostscript library */ #include "gx.h" #include "gserrors.h" --- 19,23 ---- /* gxpath.c */ ! /* Internal path construction routines for Ghostscript library */ #include "gx.h" #include "gserrors.h" *************** *** 33,37 **** private int gx_path_new_subpath(P1(gx_path *)); #ifdef DEBUG ! void gx_print_segment(P1(segment *)); #endif --- 33,37 ---- private int gx_path_new_subpath(P1(gx_path *)); #ifdef DEBUG ! void gx_print_segment(P1(const segment *)); #endif *************** *** 40,44 **** /* Initialize a path */ void ! gx_path_init(register gx_path *ppath, gs_memory_procs *pprocs) { ppath->memory_procs = *pprocs; ppath->box_last = 0; --- 40,44 ---- /* Initialize a path */ void ! gx_path_init(register gx_path *ppath, const gs_memory_procs *pprocs) { ppath->memory_procs = *pprocs; ppath->box_last = 0; *************** *** 97,106 **** /* We have to split the macro into two because of limitations */ /* on the size of a single statement (sigh). */ - #ifdef DEBUG #define p_alloc(pseg,size)\ ! if ( gs_debug['A'] ) dprintf2("[p]%lx<%u>\n", (ulong)pseg, size) ! #else ! #define p_alloc(pseg,size) 0 ! #endif #define path_unshare()\ if(ppath->shares_segments)\ --- 97,102 ---- /* We have to split the macro into two because of limitations */ /* on the size of a single statement (sigh). */ #define p_alloc(pseg,size)\ ! if_debug2('A', "[p]%lx<%u>\n", (ulong)pseg, size) #define path_unshare()\ if(ppath->shares_segments)\ *************** *** 143,147 **** #ifdef DEBUG if ( gs_debug['p'] ) ! dprintf("[p]"), gx_print_segment((segment *)spp); #endif return 0; --- 139,143 ---- #ifdef DEBUG if ( gs_debug['p'] ) ! dprintf("[p]"), gx_print_segment((const segment *)spp); #endif return 0; *************** *** 324,328 **** { gx_path path_new; int code; ! code = gx_path_copy(ppath, &path_new); if ( code < 0 ) return 0; *ppath = path_new; --- 320,324 ---- { gx_path path_new; int code; ! code = gx_path_copy(ppath, &path_new, 1); if ( code < 0 ) return 0; *ppath = path_new; *************** *** 335,341 **** #ifdef DEBUG /* Print out a path with a label */ void ! gx_dump_path(gx_path *ppath, char *tag) { dprintf2("[p]Path %lx %s:\n", (ulong)ppath, tag); gx_path_print(ppath); --- 331,340 ---- #ifdef DEBUG + /* Forward references */ + void gx_path_print(P1(const gx_path *)); + /* Print out a path with a label */ void ! gx_dump_path(const gx_path *ppath, const char *tag) { dprintf2("[p]Path %lx %s:\n", (ulong)ppath, tag); gx_path_print(ppath); *************** *** 344,349 **** /* Print a path */ void ! gx_path_print(gx_path *ppath) ! { segment *pseg = (segment *)ppath->first_subpath; dprintf4(" subpaths=%d, curves=%d, point=(%f,%f)\n", ppath->subpath_count, ppath->curve_count, --- 343,348 ---- /* Print a path */ void ! gx_path_print(const gx_path *ppath) ! { const segment *pseg = (const segment *)ppath->first_subpath; dprintf4(" subpaths=%d, curves=%d, point=(%f,%f)\n", ppath->subpath_count, ppath->curve_count, *************** *** 360,364 **** } void ! gx_print_segment(segment *pseg) { char out[80]; sprintf(out, " %lx<%lx,%lx>: %%s (%6g,%6g) ", --- 359,363 ---- } void ! gx_print_segment(const segment *pseg) { char out[80]; sprintf(out, " %lx<%lx,%lx>: %%s (%6g,%6g) ", *************** *** 368,372 **** { case s_start: ! #define psub ((subpath *)pseg) dprintf1(out, "start"); dprintf2("#curves=%d last=%lx", --- 367,371 ---- { case s_start: ! #define psub ((const subpath *)pseg) dprintf1(out, "start"); dprintf2("#curves=%d last=%lx", *************** *** 376,380 **** case s_curve: dprintf1(out, "curve"); ! #define pcur ((curve_segment *)pseg) dprintf4("\n\tp1=(%f,%f) p2=(%f,%f)", fixed2float(pcur->p1.x), fixed2float(pcur->p1.y), --- 375,379 ---- case s_curve: dprintf1(out, "curve"); ! #define pcur ((const curve_segment *)pseg) dprintf4("\n\tp1=(%f,%f) p2=(%f,%f)", fixed2float(pcur->p1.x), fixed2float(pcur->p1.y), *************** *** 386,390 **** break; case s_line_close: ! #define plc ((line_close_segment *)pseg) dprintf1(out, "close"); dprintf1(" %lx", (ulong)(plc->sub)); --- 385,389 ---- break; case s_line_close: ! #define plc ((const line_close_segment *)pseg) dprintf1(out, "close"); dprintf1(" %lx", (ulong)(plc->sub)); *************** *** 402,406 **** /* Print a clipping path */ void ! gx_cpath_print(gx_clip_path *pcpath) { if ( pcpath->segments_valid ) gx_path_print(&pcpath->path); --- 401,405 ---- /* Print a clipping path */ void ! gx_cpath_print(const gx_clip_path *pcpath) { if ( pcpath->segments_valid ) gx_path_print(&pcpath->path); diff -rc2N gs241/gxpath.h gs25/gxpath.h *** gs241/gxpath.h Sun Mar 8 19:03:32 1992 --- gs25/gxpath.h Sat Jul 18 04:39:36 1992 *************** *** 1,3 **** ! /* Copyright (C) 1989, 1990, 1991 Aladdin Enterprises. All rights reserved. Distributed by Free Software Foundation, Inc. --- 1,3 ---- ! /* Copyright (C) 1989, 1992 Aladdin Enterprises. All rights reserved. Distributed by Free Software Foundation, Inc. *************** *** 40,48 **** /* Debugging routines */ #ifdef DEBUG ! extern void gx_path_print(P1(gx_path *)); #endif /* Path constructors. */ ! extern void gx_path_init(P2(gx_path *, gs_memory_procs *)), gx_path_release(P1(gx_path *)), gx_path_share(P1(gx_path *)); --- 40,48 ---- /* Debugging routines */ #ifdef DEBUG ! extern void gx_path_print(P1(const gx_path *)); #endif /* Path constructors. */ ! extern void gx_path_init(P2(gx_path *, const gs_memory_procs *)), gx_path_release(P1(gx_path *)), gx_path_share(P1(gx_path *)); *************** *** 64,78 **** /* Path accessors */ ! extern int gx_path_current_point(P2(gx_path *, gs_fixed_point *)), gx_path_bbox(P2(gx_path *, gs_fixed_rect *)), ! gx_path_has_curves(P1(gx_path *)), ! gx_path_is_void(P1(gx_path *)), ! gx_path_is_rectangle(P2(gx_path *, gs_fixed_rect *)); /* Path transformers */ ! extern int gx_path_copy(P2(gx_path * /*old*/, gx_path * /*new*/)), ! gx_path_flatten(P3(gx_path * /*old*/, gx_path * /*new*/, floatp)), ! gx_path_reverse(P2(gx_path * /*old*/, gx_path * /*new*/)), gx_path_translate(P3(gx_path *, fixed, fixed)); --- 64,81 ---- /* Path accessors */ ! extern int gx_path_current_point(P2(const gx_path *, gs_fixed_point *)), gx_path_bbox(P2(gx_path *, gs_fixed_rect *)), ! gx_path_has_curves(P1(const gx_path *)), ! gx_path_is_void(P1(const gx_path *)), ! gx_path_is_rectangle(P2(const gx_path *, gs_fixed_rect *)); ! /* Inline versions of the above */ ! #define gx_path_is_void_inline(ppath) ((ppath)->first_subpath == 0) ! #define gx_path_has_curves_inline(ppath) ((ppath)->curve_count != 0) /* Path transformers */ ! extern int gx_path_copy(P3(const gx_path * /*old*/, gx_path * /*new*/, int /*init*/)), ! gx_path_flatten(P4(const gx_path * /*old*/, gx_path * /*new*/, floatp, int)), ! gx_path_copy_reversed(P3(const gx_path * /*old*/, gx_path * /*new*/, int /*init*/)), gx_path_translate(P3(gx_path *, fixed, fixed)); *************** *** 85,89 **** extern int gx_clip_to_rectangle(P2(gs_state *, gs_fixed_rect *)), gx_clip_to_path(P1(gs_state *)), ! gx_cpath_from_rectangle(P3(gx_clip_path *, gs_fixed_rect *, gs_memory_procs *)), gx_cpath_intersect(P4(gs_state *, gx_clip_path *, gx_path *, int)); extern void gx_cpath_release(P1(gx_clip_path *)), --- 88,92 ---- extern int gx_clip_to_rectangle(P2(gs_state *, gs_fixed_rect *)), gx_clip_to_path(P1(gs_state *)), ! gx_cpath_from_rectangle(P3(gx_clip_path *, gs_fixed_rect *, const gs_memory_procs *)), gx_cpath_intersect(P4(gs_state *, gx_clip_path *, gx_path *, int)); extern void gx_cpath_release(P1(gx_clip_path *)), *************** *** 90,95 **** gx_cpath_share(P1(gx_clip_path *)); extern int gx_cpath_path(P2(gx_clip_path *, gx_path *)), ! gx_cpath_box_for_check(P2(gx_clip_path *, gs_fixed_rect *)), ! gx_cpath_includes_rectangle(P5(gx_clip_path *, fixed, fixed, fixed, fixed)); /* Opaque type for a clip list. */ --- 93,98 ---- gx_cpath_share(P1(gx_clip_path *)); extern int gx_cpath_path(P2(gx_clip_path *, gx_path *)), ! gx_cpath_box_for_check(P2(const gx_clip_path *, gs_fixed_rect *)), ! gx_cpath_includes_rectangle(P5(const gx_clip_path *, fixed, fixed, fixed, fixed)); /* Opaque type for a clip list. */ *************** *** 103,105 **** extern int gx_clip_list_add_to_path(P2(gx_clip_list *, gx_path *)); /* Free a clip list. */ ! extern void gx_clip_list_free(P2(gx_clip_list *, gs_memory_procs *)); --- 106,108 ---- extern int gx_clip_list_add_to_path(P2(gx_clip_list *, gx_path *)); /* Free a clip list. */ ! extern void gx_clip_list_free(P2(gx_clip_list *, const gs_memory_procs *)); diff -rc2N gs241/gxpath2.c gs25/gxpath2.c *** gs241/gxpath2.c Wed Apr 8 11:30:14 1992 --- gs25/gxpath2.c Thu Aug 13 18:40:34 1992 *************** *** 27,38 **** #include "gzpath.h" - /* Forward declarations */ - private int copy_path(P3(gx_path *, gx_path *, fixed)); - private int flatten_recur(P8(gx_path *, - fixed, fixed, fixed, fixed, fixed, fixed, fixed)); - /* Read the current point of a path. */ int ! gx_path_current_point(gx_path *ppath, gs_fixed_point *ppt) { if ( !ppath->position_valid ) return_error(gs_error_nocurrentpoint); --- 27,33 ---- #include "gzpath.h" /* Read the current point of a path. */ int ! gx_path_current_point(const gx_path *ppath, gs_fixed_point *ppt) { if ( !ppath->position_valid ) return_error(gs_error_nocurrentpoint); *************** *** 99,103 **** /* Test if a path has any curves. */ int ! gx_path_has_curves(gx_path *ppath) { return ppath->curve_count != 0; } --- 94,98 ---- /* Test if a path has any curves. */ int ! gx_path_has_curves(const gx_path *ppath) { return ppath->curve_count != 0; } *************** *** 105,109 **** /* Test if a path has any segments. */ int ! gx_path_is_void(gx_path *ppath) { return ppath->first_subpath == 0; } --- 100,104 ---- /* Test if a path has any segments. */ int ! gx_path_is_void(const gx_path *ppath) { return ppath->first_subpath == 0; } *************** *** 113,119 **** /* Note that this must recognize open as well as closed rectangles. */ int ! gx_path_is_rectangle(gx_path *ppath, gs_fixed_rect *pbox) ! { subpath *pseg0; ! segment *pseg1, *pseg2, *pseg3, *pseg4; if ( ppath->subpath_count == 1 && (pseg1 = (pseg0 = ppath->first_subpath)->next) != 0 && --- 108,114 ---- /* Note that this must recognize open as well as closed rectangles. */ int ! gx_path_is_rectangle(const gx_path *ppath, gs_fixed_rect *pbox) ! { const subpath *pseg0; ! const segment *pseg1, *pseg2, *pseg3, *pseg4; if ( ppath->subpath_count == 1 && (pseg1 = (pseg0 = ppath->first_subpath)->next) != 0 && *************** *** 145,154 **** } - /* Copy a path */ - int - gx_path_copy(gx_path *ppath_old, gx_path *ppath) - { return copy_path(ppath_old, ppath, (fixed)0); - } - /* Translate an already-constructed path (in device space). */ /* Don't bother to translate the cbox. */ --- 140,143 ---- *************** *** 178,444 **** } - /* Flatten a path */ - private fixed - scale_flatness(floatp flatness) - { /* See the flattening algorithm below for an explanation of */ - /* the following computation. */ - fixed scaled_flat = float2fixed(flatness); - return (scaled_flat > int2fixed(100) ? int2fixed(100) : - scaled_flat <= float2fixed(0.2) ? float2fixed(0.2) : - scaled_flat); - } - int - gx_path_flatten(gx_path *ppath_old, gx_path *ppath, floatp flatness) - { return copy_path(ppath_old, ppath, scale_flatness(flatness)); - } - - /* Add a flattened curve to a path. */ - int - gx_path_add_flattened_curve(gx_path *ppath, - fixed x1, fixed y1, fixed x2, fixed y2, fixed x3, fixed y3, - floatp flatness) - { return flatten_recur(ppath, x1, y1, x2, y2, x3, y3, - scale_flatness(flatness)); - } - - /* Copy a path, optionally flattening it. */ - /* If the copy fails, free the new path. */ - private int - copy_path(gx_path *ppath_old, gx_path *ppath, fixed scaled_flat) - { gx_path old; - segment *pseg; - int code; - #ifdef DEBUG - if ( gs_debug['p'] ) - gx_dump_path(ppath_old, "before copy_path"); - #endif - old = *ppath_old; - gx_path_init(ppath, &ppath_old->memory_procs); - pseg = (segment *)(old.first_subpath); - while ( pseg ) - { switch ( pseg->type ) - { - case s_start: - code = gx_path_add_point(ppath, pseg->pt.x, pseg->pt.y); - break; - case s_curve: - { curve_segment *pc = (curve_segment *)pseg; - if ( scaled_flat == 0 ) /* don't flatten */ - code = gx_path_add_curve(ppath, - pc->p1.x, pc->p1.y, - pc->p2.x, pc->p2.y, - pc->pt.x, pc->pt.y); - else - code = flatten_recur(ppath, - pc->p1.x, pc->p1.y, - pc->p2.x, pc->p2.y, - pc->pt.x, pc->pt.y, - scaled_flat); - break; - } - case s_line: - code = gx_path_add_line(ppath, pseg->pt.x, pseg->pt.y); - break; - case s_line_close: - code = gx_path_close_subpath(ppath); - break; - } - if ( code ) - { gx_path_release(ppath); - if ( ppath == ppath_old ) *ppath_old = old; - return code; - } - pseg = pseg->next; - } - ppath->position = old.position; /* restore current point */ - #ifdef DEBUG - if ( gs_debug['p'] ) - gx_dump_path(ppath, "after copy_path"); - #endif - return 0; - } - /* Internal routine to flatten a curve. */ - /* This calls itself recursively, using binary subdivision, */ - /* until the approximation is good enough to satisfy the */ - /* flatness requirement. The starting point is ppath->position, */ - /* which gets updated as line segments are added. */ - - /* Table of f(i) = 256 * sqrt(1 + (i/64)^2). */ - /* This is good to within 1% or better. */ - #define sqrt_index_shift 6 /* scaling of index */ - #define sqrt_value_shift 8 /* scaling of value */ - private int scaled_sqrt_tab[65] = - { 256, 256, 256, 256, 256, 256, 257, 257, - 257, 258, 259, 259, 260, 261, 262, 262, - 263, 264, 265, 267, 268, 269, 270, 272, - 273, 274, 276, 277, 279, 281, 282, 284, - 286, 288, 289, 291, 293, 295, 297, 299, - 301, 304, 306, 308, 310, 312, 315, 317, - 320, 322, 324, 327, 329, 332, 334, 337, - 340, 342, 345, 348, 350, 353, 356, 359, - 362 - }; - private int flatten_sample(P8(gx_path *, int, - fixed, fixed, fixed, fixed, fixed, fixed)); - - private int - flatten_recur(gx_path *ppath, - fixed x1, fixed y1, fixed x2, fixed y2, fixed x3, fixed y3, - fixed scaled_flat) - { fixed - x0 = ppath->position.x, - y0 = ppath->position.y; - top: - #ifdef DEBUG - if ( gs_debug['2'] ) - dprintf4("[2]x0=%f y0=%f x1=%f y1=%f\n", - fixed2float(x0), fixed2float(y0), - fixed2float(x1), fixed2float(y1)), - dprintf4(" x2=%f y2=%f x3=%f y3=%f\n", - fixed2float(x2), fixed2float(y2), - fixed2float(x3), fixed2float(y3)); - #endif - /* - * Compute the maximum distance of the curve from - * the line (x0,y0)->(x3,y3). We do this conservatively - * by observing that the curve is enclosed by the - * quadrilateral of its control points, so we simply - * compute the distances of (x1,y1) and (x2,y2) - * from the line. Letting dx = x3-x0 and dy = y3-y0, - * the distance of (xp,yp) from the line is - * abs(N)/sqrt(D), where N = dy*(xp-x0)-dx*(yp-y0) and - * D = dx*dx+dy*dy; hence we want to test abs(N) <= sqrt(D)*F, - * where F is the flatness parameter from the graphics state. - * We can do this more efficiently by letting t=dy/dx, and - * testing abs(N1) <= sqrt(D1)*f, where N1=t*(xp-x0)-(yp-y0) and - * D1 = 1+t*t. If dx < dy, we swap x and y for this - * computation. This guarantees abs(t) <= 1, which allows us to - * compute sqrt(1+t*t) by table lookup on the high bits of abs(t). - */ - { fixed dx3 = x3 - x0; - fixed adx3 = any_abs(dx3); - fixed dy3 = y3 - y0; - fixed ady3 = any_abs(dy3); - /* We have to be quite careful to ensure that */ - /* none of the multiplications will overflow. */ - #define short_max 0x7ff0L - #define reduce_3(ad3, maxv)\ - while ( ad3 > maxv )\ - adx3 >>= 1, ady3 >>= 1,\ - dx3 = arith_rshift_1(dx3), dy3 = arith_rshift_1(dy3) - #define reduce_d(d)\ - for ( shift = 0; (d < 0 ? d < -short_max : d > short_max); shift++ )\ - d = arith_rshift_1(d) - if ( adx3 > ady3 ) - { fixed d, dx, dy, dist; - int shift; - reduce_3(ady3, short_max); - d = (scaled_sqrt_tab[(ady3 << sqrt_index_shift) / adx3] * scaled_flat) >> sqrt_value_shift; - dx = x1 - x0, dy = y1 - y0; - reduce_d(dx); - if ( ((dist = ((dx * dy3 / dx3) << shift) - dy) < 0 ? - -dist : dist) > d ) - goto sub; /* not flat enough */ - dx = x2 - x0, dy = y2 - y0; - reduce_d(dx); - if ( ((dist = ((dx * dy3 / dx3) << shift) - dy) < 0 ? - -dist : dist) > d ) - goto sub; /* not flat enough */ - } - else if ( ady3 != 0 ) - { fixed d, dy, dx, dist; - int shift; - reduce_3(adx3, short_max); - d = (scaled_sqrt_tab[(adx3 << sqrt_index_shift) / ady3] * scaled_flat) >> sqrt_value_shift; - dy = y1 - y0, dx = x1 - x0; - reduce_d(dy); - if ( ((dist = ((dy * dx3 / dy3) << shift) - dx) < 0 ? - -dist : dist) > d ) - goto sub; /* not flat enough */ - dy = y2 - y0, dx = x2 - x0; - reduce_d(dy); - if ( ((dist = ((dy * dx3 / dy3) << shift) - dx) < 0 ? - -dist : dist) > d ) - goto sub; /* not flat enough */ - } - else /* adx3 = ady3 = 0 */ - { /* (x0,y0) is the same point as (x3,y3). */ - /* This is an anomalous case. If the entire curve */ - /* is a single point, stop now, otherwise subdivide. */ - if ( x1 != x0 || y1 != y0 || x2 != x0 || y2 != y0 ) - goto sub; - } - } - /* Curve is flat enough. Add a line and exit. */ - #ifdef DEBUG - if ( gs_debug['2'] ) - dprintf2("[2]\t*** x=%f, y=%f ***\n", - fixed2float(x3), fixed2float(y3)); - #endif - return gx_path_add_line(ppath, x3, y3); - - /* Curve isn't flat enough. Break into two pieces and recur. */ - /* Algorithm is from "The Beta2-split: A special case of the */ - /* Beta-spline Curve and Surface Representation," B. A. Barsky */ - /* and A. D. DeRose, IEEE, 1985, courtesy of Crispin Goswell. */ - sub: - /* We have to define midpoint carefully to avoid overflow. */ - /* (If it overflows, something really pathological is going on, */ - /* but we could get infinite recursion that way.... */ - #define midpoint(a,b)\ - (arith_rshift_1(a) + arith_rshift_1(b) + ((a) & (b) & 1)) - { fixed x01 = midpoint(x0, x1), y01 = midpoint(y0, y1); - fixed x12 = midpoint(x1, x2), y12 = midpoint(y1, y2); - fixed x02 = midpoint(x01, x12), y02 = midpoint(y01, y12); - int code; - /* Update x/y1, x/y2, and x/y0 now for the second half. */ - x2 = midpoint(x2, x3), y2 = midpoint(y2, y3); - x1 = midpoint(x12, x2), y1 = midpoint(y12, y2); - code = flatten_recur(ppath, x01, y01, x02, y02, - (x0 = midpoint(x02, x1)), (y0 = midpoint(y02, y1)), - scaled_flat); - if ( code < 0 ) return code; - } goto top; - } - - /* Flatten a segment of the path by repeated sampling. */ - /* For some reason, this produces better results, */ - /* even though flatten_recur is careful to check the flatness.... */ - /* n is the number of points to sample, including the endpoints; */ - /* we require n >= 3. */ - private int - flatten_sample(gx_path *ppath, int n, - fixed x1, fixed y1, fixed x2, fixed y2, fixed x3, fixed y3) - { const fixed - x0 = ppath->position.x, - y0 = ppath->position.y; - const fixed - cx = 3 * (x1 - x0), - bx = 3 * (x2 - x1) - cx, - ax = x3 - bx - cx - x0; - const fixed - cy = 3 * (y1 - y0), - by = 3 * (y2 - y1) - cy, - ay = y3 - by - cy - y0; - const float - dt = 1.0 / (float)(n - 1); - int i; - - for ( i = 1; i < n-1; i++ ) - { const float t = dt * (float)(i); - const fixed x = x0 + (fixed)(t*(cx + t*(bx + t*ax))); - const fixed y = y0 + (fixed)(t*(cy + t*(by + t*ay))); - int code; - if ( 0 != (code = gx_path_add_line(ppath, x, y)) ) - return code; - } - return gx_path_add_line(ppath, x3, y3); - } - /* Reverse a path. */ /* We know ppath != ppath_old. */ int ! gx_path_reverse(gx_path *ppath_old, gx_path *ppath) ! { subpath *psub = ppath_old->first_subpath; #ifdef DEBUG if ( gs_debug['p'] ) --- 167,175 ---- } /* Reverse a path. */ /* We know ppath != ppath_old. */ int ! gx_path_copy_reversed(const gx_path *ppath_old, gx_path *ppath, int init) ! { const subpath *psub = ppath_old->first_subpath; #ifdef DEBUG if ( gs_debug['p'] ) *************** *** 445,452 **** gx_dump_path(ppath_old, "before reversepath"); #endif ! gx_path_init(ppath, &ppath_old->memory_procs); nsp: while ( psub ) ! { segment *pseg = psub->last; ! segment *prev; int code = gx_path_add_point(ppath, pseg->pt.x, pseg->pt.y); if ( code < 0 ) --- 176,184 ---- gx_dump_path(ppath_old, "before reversepath"); #endif ! if ( init ) ! gx_path_init(ppath, &ppath_old->memory_procs); nsp: while ( psub ) ! { const segment *pseg = psub->last; ! const segment *prev; int code = gx_path_add_point(ppath, pseg->pt.x, pseg->pt.y); if ( code < 0 ) *************** *** 462,469 **** if ( psub->closed ) code = gx_path_close_subpath(ppath); ! psub = (subpath *)psub->last->next; goto nsp; case s_curve: ! { curve_segment *pc = (curve_segment *)pseg; code = gx_path_add_curve(ppath, pc->p2.x, pc->p2.y, --- 194,201 ---- if ( psub->closed ) code = gx_path_close_subpath(ppath); ! psub = (const subpath *)psub->last->next; goto nsp; case s_curve: ! { const curve_segment *pc = (const curve_segment *)pseg; code = gx_path_add_curve(ppath, pc->p2.x, pc->p2.y, *************** *** 482,485 **** --- 214,218 ---- } } + /* not reached */ } ppath->position = ppath_old->position; /* restore current point */ diff -rc2N gs241/gxpcopy.c gs25/gxpcopy.c *** gs241/gxpcopy.c --- gs25/gxpcopy.c Thu Aug 13 19:48:12 1992 *************** *** 0 **** --- 1,503 ---- + /* Copyright (C) 1992 Aladdin Enterprises. All rights reserved. + Distributed by Free Software Foundation, Inc. + + This file is part of Ghostscript. + + Ghostscript is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY. No author or distributor accepts responsibility + to anyone for the consequences of using it or for whether it serves any + particular purpose or works at all, unless he says so in writing. Refer + to the Ghostscript General Public License for full details. + + Everyone is granted permission to copy, modify and redistribute + Ghostscript, but only under the conditions described in the Ghostscript + General Public License. A copy of this license is supposed to have been + given to you along with Ghostscript so you can know your rights and + responsibilities. It should be in a file named COPYING. Among other + things, the copyright notice and this notice must be preserved on all + copies. */ + + /* gxpcopy.c */ + /* Path copying and flattening for Ghostscript library */ + #include "math_.h" + #include "gx.h" + #include "gserrors.h" + #include "gxfixed.h" + #include "gxarith.h" + #include "gzpath.h" + + /* Forward declarations */ + private int copy_path(P4(const gx_path *, gx_path *, fixed, int)); + private int flatten_recur(P8(gx_path *, + fixed, fixed, fixed, fixed, fixed, fixed, fixed)); + private int flatten_sample(P8(gx_path *, int, + fixed, fixed, fixed, fixed, fixed, fixed)); + + /* Copy a path */ + int + gx_path_copy(const gx_path *ppath_old, gx_path *ppath, int init) + { return copy_path(ppath_old, ppath, max_fixed, init); + } + + /* Flatten a path. */ + /* If flatness is zero, use sampling rather than subdivision: */ + /* this is important for Type 1 fonts. */ + private fixed + scale_flatness(floatp flatness) + { fixed scaled_flat = float2fixed(flatness); + return (scaled_flat > int2fixed(100) ? int2fixed(100) : + scaled_flat < fixed_half ? fixed_0 : + scaled_flat); + } + int + gx_path_flatten(const gx_path *ppath_old, gx_path *ppath, floatp flatness, int in_BuildChar) + { return copy_path(ppath_old, ppath, + (in_BuildChar ? fixed_0 : scale_flatness(flatness)), + 1); + } + + /* Add a flattened curve to a path. */ + int + gx_path_add_flattened_curve(gx_path *ppath, + fixed x1, fixed y1, fixed x2, fixed y2, fixed x3, fixed y3, + floatp flatness) + { return flatten_recur(ppath, x1, y1, x2, y2, x3, y3, + scale_flatness(flatness)); + } + + /* Copy a path, optionally flattening it. */ + /* If the copy fails, free the new path. */ + private int + copy_path(const gx_path *ppath_old, gx_path *ppath, fixed scaled_flat, + int init) + { gx_path old; + const segment *pseg; + int code; + #ifdef DEBUG + if ( gs_debug['p'] ) + gx_dump_path(ppath_old, "before copy_path"); + #endif + old = *ppath_old; + if ( init ) + gx_path_init(ppath, &ppath_old->memory_procs); + pseg = (const segment *)(old.first_subpath); + while ( pseg ) + { switch ( pseg->type ) + { + case s_start: + code = gx_path_add_point(ppath, pseg->pt.x, pseg->pt.y); + break; + case s_curve: + { curve_segment *pc = (curve_segment *)pseg; + if ( scaled_flat == max_fixed ) /* don't flatten */ + code = gx_path_add_curve(ppath, + pc->p1.x, pc->p1.y, + pc->p2.x, pc->p2.y, + pc->pt.x, pc->pt.y); + else + code = flatten_recur(ppath, + pc->p1.x, pc->p1.y, + pc->p2.x, pc->p2.y, + pc->pt.x, pc->pt.y, + scaled_flat); + break; + } + case s_line: + code = gx_path_add_line(ppath, pseg->pt.x, pseg->pt.y); + break; + case s_line_close: + code = gx_path_close_subpath(ppath); + break; + } + if ( code ) + { gx_path_release(ppath); + if ( ppath == ppath_old ) + *ppath = old; + return code; + } + pseg = pseg->next; + } + ppath->position = old.position; /* restore current point */ + #ifdef DEBUG + if ( gs_debug['p'] ) + gx_dump_path(ppath, "after copy_path"); + #endif + return 0; + } + /* Internal routine to flatten a curve. */ + /* This calls itself recursively, using binary subdivision, */ + /* until the approximation is good enough to satisfy the */ + /* flatness requirement. The starting point is ppath->position, */ + /* which gets updated as line segments are added. */ + + /* Maximum number of points for sampling if we want accurate rasterizing. */ + /* (num_sample_max - 1)^3 must fit into an int. */ + #define num_sample_max (1 << ((sizeof(int) * 8 - 1) / 3)) + + /* Table of f(i) = 256 * sqrt(1 + (i/64)^2). */ + /* This is good to within 1% or better. */ + #define sqrt_index_shift 6 /* scaling of index */ + #define sqrt_value_shift 8 /* scaling of value */ + private int scaled_sqrt_tab[65] = + { 256, 256, 256, 256, 256, 256, 257, 257, + 257, 258, 259, 259, 260, 261, 262, 262, + 263, 264, 265, 267, 268, 269, 270, 272, + 273, 274, 276, 277, 279, 281, 282, 284, + 286, 288, 289, 291, 293, 295, 297, 299, + 301, 304, 306, 308, 310, 312, 315, 317, + 320, 322, 324, 327, 329, 332, 334, 337, + 340, 342, 345, 348, 350, 353, 356, 359, + 362 + }; + + private int + flatten_recur(gx_path *ppath, + fixed x1, fixed y1, fixed x2, fixed y2, fixed x3, fixed y3, + fixed scaled_flat) + { fixed + x0 = ppath->position.x, + y0 = ppath->position.y; + top: + #ifdef DEBUG + if ( gs_debug['2'] ) + dprintf4("[2]x0=%f y0=%f x1=%f y1=%f\n", + fixed2float(x0), fixed2float(y0), + fixed2float(x1), fixed2float(y1)), + dprintf4(" x2=%f y2=%f x3=%f y3=%f\n", + fixed2float(x2), fixed2float(y2), + fixed2float(x3), fixed2float(y3)); + #endif + /* + * Compute the maximum distance of the curve from + * the line (x0,y0)->(x3,y3). We do this conservatively + * by observing that the curve is enclosed by the + * quadrilateral of its control points, so we simply + * compute the distances of (x1,y1) and (x2,y2) + * from the line. Letting dx = x3-x0 and dy = y3-y0, + * the distance of (xp,yp) from the line is + * abs(N)/sqrt(D), where N = dy*(xp-x0)-dx*(yp-y0) and + * D = dx*dx+dy*dy; hence we want to test abs(N) <= sqrt(D)*F, + * where F is the flatness parameter from the graphics state. + * We can do this more efficiently by letting t=dy/dx, and + * testing abs(N1) <= sqrt(D1)*f, where N1=t*(xp-x0)-(yp-y0) and + * D1 = 1+t*t. If dx < dy, we swap x and y for this + * computation. This guarantees abs(t) <= 1, which allows us to + * compute sqrt(1+t*t) by table lookup on the high bits of abs(t). + * + * To avoid replacing shallow curves by long straight lines, + * we also require that abs(dx) and abs(dy) be reasonably small. + * + * Note that if scaled_flat is very small, we don't do any of this; + * instead, we just check whether abs(dx) and abs(dy) are + * small enough to switch over to sampling rather than dividing. + */ + { fixed dx3 = x3 - x0; + fixed adx3 = any_abs(dx3); + fixed dy3 = y3 - y0; + fixed ady3 = any_abs(dy3); + /* We have to be quite careful to ensure that */ + /* none of the multiplications will overflow. */ + #define short_max 0x7ff0L + #define reduce_3(ad3, maxv)\ + while ( ad3 > maxv )\ + adx3 >>= 1, ady3 >>= 1,\ + dx3 = arith_rshift_1(dx3), dy3 = arith_rshift_1(dy3) + #define reduce_d(d)\ + for ( shift = 0; (d < 0 ? d < -short_max : d > short_max); shift++ )\ + d = arith_rshift_1(d) + if ( adx3 > ady3 ) + { fixed d, dx, dy, dist; + int shift; + if ( scaled_flat == 0 ) + { if ( adx3 < int2fixed(num_sample_max / 2) ) + { int n = fixed2int_var_rounded(adx3) * 2 + 1; + return flatten_sample(ppath, max(n, 3), x1, y1, + x2, y2, x3, y3); + } + else goto sub; + } + else if ( adx3 > scaled_flat << 1 ) + goto sub; + reduce_3(ady3, short_max); + d = (scaled_sqrt_tab[(ady3 << sqrt_index_shift) / adx3] * scaled_flat) >> sqrt_value_shift; + dx = x1 - x0, dy = y1 - y0; + reduce_d(dx); + if ( ((dist = ((dx * dy3 / dx3) << shift) - dy) < 0 ? + -dist : dist) > d ) + goto sub; /* not flat enough */ + dx = x2 - x0, dy = y2 - y0; + reduce_d(dx); + if ( ((dist = ((dx * dy3 / dx3) << shift) - dy) < 0 ? + -dist : dist) > d ) + goto sub; /* not flat enough */ + } + else if ( ady3 != 0 ) + { fixed d, dy, dx, dist; + int shift; + if ( scaled_flat == 0 ) + { if ( ady3 < int2fixed(num_sample_max / 2) ) + { int n = fixed2int_var_rounded(ady3) * 2 + 1; + return flatten_sample(ppath, max(n, 3), x1, y1, + x2, y2, x3, y3); + } + else goto sub; + } + else if ( ady3 > scaled_flat << 1 ) + goto sub; + reduce_3(adx3, short_max); + d = (scaled_sqrt_tab[(adx3 << sqrt_index_shift) / ady3] * scaled_flat) >> sqrt_value_shift; + dy = y1 - y0, dx = x1 - x0; + reduce_d(dy); + if ( ((dist = ((dy * dx3 / dy3) << shift) - dx) < 0 ? + -dist : dist) > d ) + goto sub; /* not flat enough */ + dy = y2 - y0, dx = x2 - x0; + reduce_d(dy); + if ( ((dist = ((dy * dx3 / dy3) << shift) - dx) < 0 ? + -dist : dist) > d ) + goto sub; /* not flat enough */ + } + else /* adx3 = ady3 = 0 */ + { /* (x0,y0) is the same point as (x3,y3). */ + /* This is an anomalous case. If the entire curve */ + /* is a single point, stop now, otherwise subdivide. */ + if ( x1 != x0 || y1 != y0 || x2 != x0 || y2 != y0 ) + goto sub; + } + } + /* Curve is flat enough. Add a line and exit. */ + #ifdef DEBUG + if ( gs_debug['2'] ) + dprintf2("[2]\t*** x=%f, y=%f ***\n", + fixed2float(x3), fixed2float(y3)); + #endif + return gx_path_add_line(ppath, x3, y3); + + /* Curve isn't flat enough. Break into two pieces and recur. */ + /* Algorithm is from "The Beta2-split: A special case of the */ + /* Beta-spline Curve and Surface Representation," B. A. Barsky */ + /* and A. D. DeRose, IEEE, 1985, courtesy of Crispin Goswell. */ + sub: + /* We have to define midpoint carefully to avoid overflow. */ + /* (If it overflows, something really pathological is going on, */ + /* but we could get infinite recursion that way....) */ + #define midpoint(a,b)\ + (arith_rshift_1(a) + arith_rshift_1(b) + ((a) & (b) & 1)) + { fixed x01 = midpoint(x0, x1), y01 = midpoint(y0, y1); + fixed x12 = midpoint(x1, x2), y12 = midpoint(y1, y2); + fixed x02 = midpoint(x01, x12), y02 = midpoint(y01, y12); + int code; + /* Update x/y1, x/y2, and x/y0 now for the second half. */ + x2 = midpoint(x2, x3), y2 = midpoint(y2, y3); + x1 = midpoint(x12, x2), y1 = midpoint(y12, y2); + code = flatten_recur(ppath, x01, y01, x02, y02, + (x0 = midpoint(x02, x1)), (y0 = midpoint(y02, y1)), + scaled_flat); + if ( code < 0 ) return code; + } goto top; + } + + /* Flatten a segment of the path by repeated sampling. */ + /* n is the number of points to sample, including the endpoints; */ + /* we require n >= 3. */ + private int + flatten_sample(gx_path *ppath, int n, + fixed x1, fixed y1, fixed x2, fixed y2, fixed x3, fixed y3) + { const fixed + x0 = ppath->position.x, + y0 = ppath->position.y; + /* We spell out some multiplies by 3, */ + /* for the benefit of compilers that don't optimize this. */ + const fixed + x01 = x1 - x0, + cx = (x01 << 1) + x01, /* 3*(x1-x0) */ + x12 = x2 - x1, + bx = (x12 << 1) + x12 - cx, /* 3*(x2-2*x1+x0) */ + ax = x3 - bx - cx - x0; /* x3-3*x2+3*x1-x0 */ + const fixed + y01 = y1 - y0, + cy = (y01 << 1) + y01, + y12 = y2 - y1, + by = (y12 << 1) + y12 - cy, + ay = y3 - by - cy - y0; + const int + n1 = n - 1, + n12 = n1 * n1, + n13 = n12 * n1; + fixed ptx = x0, pty = y0; + fixed x, y; + /* + * If all the coefficients lie between min_fast and max_fast, + * we can do everything in fixed point. In this case we compute + * successive values by finite differences, using the formulas: + x(t) = + a*t^3 + b*t^2 + c*t + d => + dx(t) = x(t+e)-x(t) = + a*(3*t^2*e + 3*t*e^2 + e^3) + b*(2*t*e + e^2) + c*e = + (3*a*e)*t^2 + (3*a*e^2 + 2*b*e)*t + (a*e^3 + b*e^2 + c*e) => + d2x(t) = dx(t+e)-dx(t) = + (3*a*e)*(2*t*e + e^2) + (3*a*e^2 + 2*b*e)*e = + (6*a*e^2)*t + (6*a*e^3 + 2*b*e^2) => + d3x(t) = d2x(t+e)-d2x(t) = + 6*a*e^3; + x(0) = d, dx(0) = (a*e^3 + b*e^2 + c*e), + d2x(0) = 6*a*e^3 + 2*b*e^2; + * In these formulas, e = 1/n1; of course, there are separate + * computations for the x and y values. + */ + #define max_fast (max_fixed / 6) + #define min_fast (-max_fast) + int fast; + float dt; /* only if !fast */ + int i; + /* + * We do exact rational arithmetic to avoid accumulating error. + * Each quantity is represented as I+R/n13, where I is an "integer" + * and the "remainder" R lies in the range 0 <= R < n13. Note that + * R may temporarily exceed n13, and hence possibly overflow. + */ + fixed idx, idy, id2x, id2y, id3x, id3y; /* I */ + int rx, ry, rdx, rdy, rd2x, rd2y, rd3x, rd3y; + + if_debug6('2', "[2]ax=%f bx=%f cx=%f\n ay=%f by=%f cy=%f\n", + fixed2float(ax), fixed2float(bx), fixed2float(cx), + fixed2float(ay), fixed2float(by), fixed2float(cy)); + #define in_range(v) (v < max_fast && v > min_fast) + if ( n1 < num_sample_max && /* so n13 fits */ + in_range(ax) && in_range(bx) && in_range(cx) && + in_range(ay) && in_range(by) && in_range(cy) + ) + { fast = 1; + x = x0, y = y0; + rx = ry = 0; + /* Fast check for n == 3, a common special case */ + /* for small characters. */ + if ( n == 3 ) + #define poly2(a,b,c)\ + arith_rshift_1(arith_rshift_1(arith_rshift_1(a) + b) + c) + idx = poly2(ax, bx, cx), + idy = poly2(ay, by, cy), + rdx = rdy = 0; + #undef poly2 + else + { fixed bx2 = bx << 1, by2 = by << 1; + fixed ax6 = ((ax << 1) + ax) << 1, + ay6 = ((ay << 1) + ay) << 1; + fixed qx, qy; + #define adjust_rem(r, q)\ + if ( r < 0 ) r += n13, q-- + #define adjust_rem_loop(r, q)\ + while ( r < 0 ) r += n13, q--;\ + while ( r >= n13 ) r -= n13, q++ + /* We can compute all the remainders as ints, */ + /* because we know they are less than n13. */ + /* bx/y terms */ + id2x = bx2 / n12, id2y = by2 / n12; + rd2x = ((int)bx2 - (int)id2x * n12) * n1, + rd2y = ((int)by2 - (int)id2y * n12) * n1; + idx = bx / n12, idy = by / n12; + rdx = ((int)bx - (int)idx * n12) * n1, + rdy = ((int)by - (int)idy * n12) * n1; + /* cx/y terms */ + idx += qx = cx / n1, idy += qy = cy / n1; + rdx += ((int)cx - (int)qx * n1) * n12, + rdy += ((int)cy - (int)qy * n1) * n12; + /* ax/y terms */ + idx += qx = ax / n13, idy += qy = ay / n13; + rdx += (int)ax - (int)qx * n13, + rdy += (int)ay - (int)qy * n13; + id2x += id3x = ax6 / n13, id2y += id3y = ay6 / n13; + rd2x += rd3x = (int)ax6 - (int)id3x * n13, + rd2y += rd3y = (int)ay6 - (int)id3y * n13; + adjust_rem_loop(rdx, idx); + adjust_rem_loop(rdy, idy); + adjust_rem_loop(rd2x, id2x); + adjust_rem_loop(rd2y, id2y); + adjust_rem(rd3x, id3x); + adjust_rem(rd3y, id3y); + #undef adjust_rem + #undef adjust_rem_loop + } + } + else + fast = 0, dt = 1.0 / (float)n1; + if_debug4('2', "[2]sampling %s n=%d\n[2]x=%g, y=%g\n", + (fast ? "fast" : "slow"), n, + fixed2float(x), fixed2float(y)); + for ( i = 1; i < n1; i++ ) + { int code; + if ( fast ) + { + #ifdef DEBUG + if ( gs_debug['2'] ) + dprintf4("[2]dx=%f+%d, dy=%f+%d\n", + fixed2float(idx), rdx, + fixed2float(idy), rdy), + dprintf4(" d2x=%f+%d, d2y=%f+%d\n", + fixed2float(id2x), rd2x, + fixed2float(id2y), rd2y), + dprintf4(" d3x=%f+%d, d3y=%f+%d\n", + fixed2float(id3x), rd3x, + fixed2float(id3y), rd3y); + #endif + #define accum(i, r, di, dr)\ + if ( (unsigned)(r += dr) >= (unsigned)n13 ) r -= n13, i++;\ + i += di + accum(x, rx, idx, rdx); + accum(idx, rdx, id2x, rd2x); + accum(id2x, rd2x, id3x, rd3x); + accum(y, ry, idy, rdy); + accum(idy, rdy, id2y, rd2y); + accum(id2y, rd2y, id3y, rd3y); + #undef accum + } + else + { const float t = dt * (float)(i); + x = ((ax*t + bx)*t + cx)*t + x0; + y = ((ay*t + by)*t + cy)*t + y0; + } + if_debug3('2', "[2]%s x=%g, y=%g\n", + (((x ^ ptx) | (y ^ pty)) & float2fixed(-0.5) ? + "add" : "skip"), + fixed2float(x), fixed2float(y)); + /* Skip very short segments */ + if ( ((x ^ ptx) | (y ^ pty)) & float2fixed(-0.5) ) + { if ( (code = gx_path_add_line(ppath, x, y)) < 0 ) + return code; + ptx = x, pty = y; + } + } + if_debug2('2', "[2]last x=%g, y=%g\n", + fixed2float(x3), fixed2float(y3)); + return gx_path_add_line(ppath, x3, y3); + } + + /* + * The rest of this file is an analysis that will eventually + * allow us to rasterize curves on the fly, by finding points + * where Y reaches a local maximum or minimum, which allows us to + * divide the curve into locally Y-monotonic sections. + */ + + /* + Let y(t) = a*t^3 + b*t^2 + c*t + d, 0 <= t <= 1. + Then dy(t) = 3*a*t^2 + 2*b*t + c. + y(t) has a local minimum or maximum (or inflection point) + precisely where dy(t) = 0. Now the roots of dy(t) are + ( -2*b +/- sqrt(4*b^2 - 12*a*c) ) / 6*a + = ( -b +/- sqrt(b*2 - 3*a*c) ) / 3*a + (Note that real roots exist iff b^2 >= 3*a*c.) + We want to know if these lie in the range (0..1). + (We don't care about the endpoints.) Call such a root + a "valid zero." We proceed as follows: + If sign(3*a + 2*b + c) ~= sign(c), a valid zero exists. + If sign(a) = sign(b), no valid zero exists. + Otherwise, we look for a local extremum of dy(t) by observing + d2y(t) = 6*a*t + 2*b + which has a zero only at + t1 = -b / 3*a + Now if t1 <= 0 or t1 >= 1, no valid zero exists. Otherwise, + we compute + dy(t1) = c - (b^2 / 3*a) + Then a valid zero exists (at t1) iff sign(dy(t1)) ~= sign(c). + */ diff -rc2N gs241/gxstroke.c gs25/gxstroke.c *** gs241/gxstroke.c Sat Apr 18 15:30:40 1992 --- gs25/gxstroke.c Sun Jul 19 17:24:54 1992 *************** *** 22,25 **** --- 22,26 ---- #include "math_.h" #include "gx.h" + #include "gpcheck.h" #include "gserrors.h" #include "gxfixed.h" *************** *** 26,29 **** --- 27,31 ---- #include "gxarith.h" #include "gxmatrix.h" + #include "gscoord.h" #include "gzstate.h" #include "gzdevice.h" *************** *** 32,38 **** #include "gzpath.h" ! /* stroke_add uses the following global for its path: */ ! private gx_path stroke_path_body; ! private gx_path *stroke_path; /* --- 34,39 ---- #include "gzpath.h" ! /* Define the filling adjustment that actually produces no adjustment. */ ! #define fill_no_adjust ((fixed)1) /* *************** *** 72,85 **** /* end cap. If the first int is 0, the procedure also starts with */ /* an appropriate cap. */ ! private int stroke_add(P4(int, pl_ptr, pl_ptr, gs_state *)); ! private int stroke_fill(P4(int, pl_ptr, pl_ptr, gs_state *)); /* Other forward declarations */ ! private int stroke(P3(gx_path *, ! int (*)(P4(int, pl_ptr, pl_ptr, gs_state *)), gs_state *)); ! private int expand_dashes(P3(subpath *, gx_path *, gs_state *)); ! private void compute_caps(P1(pl_ptr)); ! private int add_capped(P4(gx_path *, gs_line_cap, int (*)(P3(gx_path *, fixed, fixed)), ep_ptr)); --- 73,87 ---- /* end cap. If the first int is 0, the procedure also starts with */ /* an appropriate cap. */ ! private int near stroke_add(P5(gx_path *, int, pl_ptr, pl_ptr, gs_state *)); ! private int near stroke_fill(P5(gx_path *, int, pl_ptr, pl_ptr, gs_state *)); /* Other forward declarations */ ! private int near stroke(P4(const gx_path *, gx_path *, ! int near (*)(P5(gx_path *, int, pl_ptr, pl_ptr, gs_state *)), gs_state *)); ! private void near adjust_stroke(P2(pl_ptr, gs_state *)); ! private int near expand_dashes(P3(const subpath *, gx_path *, gs_state *)); ! private void near compute_caps(P1(pl_ptr)); ! private int near add_capped(P4(gx_path *, gs_line_cap, int (*)(P3(gx_path *, fixed, fixed)), ep_ptr)); *************** *** 87,106 **** /* Stroke a path for drawing or saving */ int ! gx_stroke_fill(gx_path *ppath, gs_state *pgs) ! { int code; ! stroke_path = 0; ! code = stroke(ppath, stroke_fill, pgs); ! if ( stroke_path ) /* set if filling needed */ ! { if ( code >= 0 ) ! code = gx_fill_path(stroke_path, pgs->dev_color, pgs, ! gx_rule_winding_number, (fixed)0); ! gx_path_release(stroke_path); ! } ! return code; } int ! gx_stroke_add(gx_path *ppath, gx_path *topath, gs_state *pgs) ! { stroke_path = topath; ! return stroke(ppath, stroke_add, pgs); } --- 89,109 ---- /* Stroke a path for drawing or saving */ int ! gx_stroke_fill(const gx_path *ppath, gs_state *pgs) ! { return stroke(ppath, (gx_path *)0, stroke_fill, pgs); } int ! gx_stroke_add(const gx_path *ppath, gx_path *to_path, gs_state *pgs) ! { return stroke(ppath, to_path, stroke_add, pgs); ! } ! ! /* Fill a partial stroked path. */ ! /* Free variables: code, to_path, ppath, stroke_path_body, pgs, exit (label). */ ! #define fill_stroke_path()\ ! if(to_path==&stroke_path_body && !gx_path_is_void_inline(&stroke_path_body))\ ! { code = gx_fill_path(to_path, pgs->dev_color, pgs, gx_rule_winding_number,\ ! fill_no_adjust);\ ! gx_path_release(to_path);\ ! if ( code < 0 ) goto exit;\ ! gx_path_init(to_path, &ppath->memory_procs);\ } *************** *** 107,120 **** /* Stroke a path. Call line_proc (stroke_add or stroke_fill) */ /* for each line segment. */ ! private int ! stroke(gx_path *ppath, ! int (*line_proc)(P4(int, pl_ptr, pl_ptr, gs_state *)), gs_state *pgs) ! { subpath *psub; ! subpath *save_psub = 0; int code = 0; ! line_params *lp = pgs->line_params; int dash_count = lp->dash.pattern_size; gx_path fpath, dpath; float xx = pgs->ctm.xx, xy = pgs->ctm.xy; float yx = pgs->ctm.yx, yy = pgs->ctm.yy; --- 110,124 ---- /* Stroke a path. Call line_proc (stroke_add or stroke_fill) */ /* for each line segment. */ ! private int near ! stroke(const gx_path *ppath, gx_path *to_path, ! int near (*line_proc)(P5(gx_path *, int, pl_ptr, pl_ptr, gs_state *)), gs_state *pgs) ! { const subpath *psub; ! const subpath *save_psub = 0; int code = 0; ! const line_params *lp = pgs->line_params; int dash_count = lp->dash.pattern_size; gx_path fpath, dpath; + gx_path stroke_path_body; float xx = pgs->ctm.xx, xy = pgs->ctm.xy; float yx = pgs->ctm.yx, yy = pgs->ctm.yy; *************** *** 132,136 **** float line_width = lp->width; /* this is *half* the line width! */ int always_thin; ! float line_width_and_scale; #ifdef DEBUG if ( gs_debug['o'] ) --- 136,140 ---- float line_width = lp->width; /* this is *half* the line width! */ int always_thin; ! double line_width_and_scale, line_width_scale_xx; #ifdef DEBUG if ( gs_debug['o'] ) *************** *** 167,176 **** ((max(xsq, ysq) + cross) * line_width * line_width < 0.5); } ! line_width_and_scale = line_width * (float)int2fixed(1); ! #ifdef DEBUG ! if ( gs_debug['o'] ) ! dprintf5("[o]ctm=(%g,%g,%g,%g) thin=%d\n", ! xx, xy, yx, yy, always_thin); ! #endif /* Start by flattening the path. We should do this on-the-fly.... */ if ( !ppath->curve_count ) /* don't need to flatten */ --- 171,183 ---- ((max(xsq, ysq) + cross) * line_width * line_width < 0.5); } ! line_width_and_scale = line_width * (double)int2fixed(1); ! if ( !always_thin && uniform ) ! { /* Precompute a value we'll need later. */ ! line_width_scale_xx = line_width_and_scale * xx; ! if ( line_width_scale_xx < 0 ) ! line_width_scale_xx = -line_width_scale_xx; ! } ! if_debug5('o', "[o]ctm=(%g,%g,%g,%g) thin=%d\n", ! xx, xy, yx, yy, always_thin); /* Start by flattening the path. We should do this on-the-fly.... */ if ( !ppath->curve_count ) /* don't need to flatten */ *************** *** 179,183 **** } else ! { if ( (code = gx_path_flatten(ppath, &fpath, pgs->flatness)) < 0 ) return code; psub = fpath.first_subpath; } --- 186,191 ---- } else ! { if ( (code = gx_path_flatten(ppath, &fpath, pgs->flatness, (int)pgs->in_cachedevice)) < 0 ) ! return code; psub = fpath.first_subpath; } *************** *** 184,189 **** if ( dash_count ) gx_path_init(&dpath, &ppath->memory_procs); for ( ; ; ) ! { line_segment *pline; fixed x, y; partial_line pl, pl_prev, pl_first; --- 192,202 ---- if ( dash_count ) gx_path_init(&dpath, &ppath->memory_procs); + if ( to_path == 0 ) + { /* We might try to defer this if it's expensive.... */ + to_path = &stroke_path_body; + gx_path_init(to_path, &ppath->memory_procs); + } for ( ; ; ) ! { const line_segment *pline; fixed x, y; partial_line pl, pl_prev, pl_first; *************** *** 194,198 **** if ( save_psub ) { gx_path_release(&dpath); ! psub = (subpath *)save_psub->last->next; if ( !psub ) break; gx_path_init(&dpath, &ppath->memory_procs); --- 207,211 ---- if ( save_psub ) { gx_path_release(&dpath); ! psub = (const subpath *)save_psub->last->next; if ( !psub ) break; gx_path_init(&dpath, &ppath->memory_procs); *************** *** 209,213 **** continue; /* psub might be null */ } ! pline = (line_segment *)(psub->next); x = psub->pt.x; y = psub->pt.y; --- 222,226 ---- continue; /* psub might be null */ } ! pline = (const line_segment *)(psub->next); x = psub->pt.x; y = psub->pt.y; *************** *** 237,243 **** { /* We can save a lot of work in this case. */ float dpx = udx, dpy = udy; ! float wl = line_width_and_scale * xx / hypot(dpx, dpy); - if ( wl < 0 ) wl = -wl; pl.e.cdelta.x = (fixed)(dpx * wl); pl.e.cdelta.y = (fixed)(dpy * wl); --- 250,255 ---- { /* We can save a lot of work in this case. */ float dpx = udx, dpy = udy; ! float wl = line_width_scale_xx / hypot(dpx, dpy); pl.e.cdelta.x = (fixed)(dpx * wl); pl.e.cdelta.y = (fixed)(dpy * wl); *************** *** 250,259 **** { gs_point dpt; /* unscaled */ float wl; ! if ( skewed ) ! gs_idtransform(pgs, (float)udx, (float)udy, &dpt); - else /* shortcut */ - dpt.x = udx / xx, - dpt.y = udy / yy; wl = line_width_and_scale / hypot(dpt.x, dpt.y); --- 262,267 ---- { gs_point dpt; /* unscaled */ float wl; ! gs_idtransform_inline(pgs, (float)udx, (float)udy, &dpt); wl = line_width_and_scale / hypot(dpt.x, dpt.y); *************** *** 289,295 **** float2fixed(0.75); } ! if ( !pl.thin ) compute_caps(&pl); } ! else pl.e.cdelta.x = pl.e.cdelta.y = 0, pl.width.x = pl.width.y = 0, --- 297,306 ---- float2fixed(0.75); } ! if ( !pl.thin ) ! { adjust_stroke(&pl, pgs); ! compute_caps(&pl); ! } } ! else /* always_thin */ pl.e.cdelta.x = pl.e.cdelta.y = 0, pl.width.x = pl.width.y = 0, *************** *** 296,319 **** pl.thin = 1; if ( first++ == 0 ) pl_first = pl; ! if ( index++ ) (*line_proc)(index - 2, &pl_prev, &pl, pgs); pl_prev = pl; x = sx, y = sy; ! nd: pline = (line_segment *)(pline->next); } if ( index ) { /* If closed, join back to start, else cap */ ! (*line_proc)(index - 1, &pl_prev, (psub->closed ? &pl_first : (pl_ptr)0), pgs); ! } ! psub = (subpath *)pline; ! if ( stroke_path == &stroke_path_body ) ! { /* Fill and release the accumulated path */ ! gx_fill_path(stroke_path, pgs->dev_color, pgs, ! gx_rule_winding_number, (fixed)0); ! gx_path_release(stroke_path); ! stroke_path = 0; } } ! exit: if ( dash_count ) gx_path_release(&dpath); if ( ppath->curve_count ) gx_path_release(&fpath); return code; --- 307,331 ---- pl.thin = 1; if ( first++ == 0 ) pl_first = pl; ! if ( index++ ) ! { code = (*line_proc)(to_path, index - 2, &pl_prev, &pl, pgs); ! if ( code < 0 ) goto exit; ! fill_stroke_path(); ! } pl_prev = pl; x = sx, y = sy; ! nd: pline = (const line_segment *)(pline->next); } if ( index ) { /* If closed, join back to start, else cap */ ! code = (*line_proc)(to_path, index - 1, &pl_prev, (psub->closed ? &pl_first : (pl_ptr)0), pgs); ! if ( code < 0 ) goto exit; ! fill_stroke_path(); } + psub = (const subpath *)pline; } ! exit: if ( to_path == &stroke_path_body ) ! gx_path_release(to_path); /* (only needed if error) */ ! if ( dash_count ) gx_path_release(&dpath); if ( ppath->curve_count ) gx_path_release(&fpath); return code; *************** *** 322,332 **** /* ------ Internal routines ------ */ /* Expand a dashed subpath into explicit segments. */ /* The subpath contains no curves. */ ! private int ! expand_dashes(subpath *psub, gx_path *ppath, gs_state *pgs) ! { int skewed = is_skewed(&pgs->ctm); ! dash_params *dash = &pgs->line_params->dash; ! float *pattern = dash->pattern; int count, ink_on, index; float dist_left; --- 334,383 ---- /* ------ Internal routines ------ */ + /* Adjust the endpoints and width of a stroke segment */ + /* to achieve more uniform rendering. */ + /* Only o.p, e.p, o.cdelta, and width have been set. */ + private void near + adjust_stroke(pl_ptr plp, gs_state *pgs) + { fixed _ss *pw; + fixed _ss *pov; + fixed _ss *pev; + fixed w2; + if ( !pgs->stroke_adjust && plp->width.x != 0 && plp->width.y != 0 ) + return; /* don't adjust */ + if ( any_abs(plp->width.x) < any_abs(plp->width.y) ) + { /* More horizontal stroke */ + pw = &plp->width.y, pov = &plp->o.p.y, pev = &plp->e.p.y; + } + else + { /* More vertical stroke */ + pw = &plp->width.x, pov = &plp->o.p.x, pev = &plp->e.p.x; + } + /* Round the larger component of the width up or down, */ + /* whichever way produces a result closer to the correct width. */ + /* Note that just rounding the larger component */ + /* may not produce the correct result. */ + w2 = fixed_rounded(*pw << 1); /* full line width */ + if ( w2 == 0 && *pw != 0 ) + { /* Make sure thin lines don't disappear. */ + w2 = (*pw < 0 ? -fixed_1 : fixed_1); + } + *pw = arith_rshift_1(w2); + /* Only adjust the endpoints if the line is horizontal or vertical. */ + if ( *pov == *pev ) + { if ( w2 & fixed_1 ) /* odd width, move to half-pixel */ + { *pov = *pev = fixed_truncated(*pov) + fixed_half; + } + else /* even width, move to pixel */ + { *pov = *pev = fixed_rounded(*pov); + } + } + } + /* Expand a dashed subpath into explicit segments. */ /* The subpath contains no curves. */ ! private int near ! expand_dashes(const subpath *psub, gx_path *ppath, gs_state *pgs) ! { const dash_params *dash = &pgs->line_params->dash; ! const float *pattern = dash->pattern; int count, ink_on, index; float dist_left; *************** *** 333,337 **** fixed x0 = psub->pt.x, y0 = psub->pt.y; fixed x, y; ! segment *pseg; int wrap = (dash->init_ink_on && psub->closed ? -1 : 0); int drawing = wrap; --- 384,388 ---- fixed x0 = psub->pt.x, y0 = psub->pt.y; fixed x, y; ! const segment *pseg; int wrap = (dash->init_ink_on && psub->closed ? -1 : 0); int drawing = wrap; *************** *** 348,352 **** dist_left = dash->init_dist_left; x = x0, y = y0; ! pseg = (segment *)psub; while ( (pseg = pseg->next) != 0 && pseg->type != s_start ) { fixed sx = pseg->pt.x, sy = pseg->pt.y; --- 399,403 ---- dist_left = dash->init_dist_left; x = x0, y = y0; ! pseg = (const segment *)psub; while ( (pseg = pseg->next) != 0 && pseg->type != s_start ) { fixed sx = pseg->pt.x, sy = pseg->pt.y; *************** *** 359,369 **** { gs_point d; dx = udx, dy = udy; /* scaled as fixed */ ! if ( skewed ) ! gs_idtransform(pgs, dx, dy, &d); ! else /* shortcut */ ! d.x = dx / pgs->ctm.xx, ! d.y = dy / pgs->ctm.yy; ! length = sqrt(d.x * d.x + d.y * d.y) * ! (1 / (float)int2fixed(1)); } dist = length; --- 410,415 ---- { gs_point d; dx = udx, dy = udy; /* scaled as fixed */ ! gs_idtransform_inline(pgs, dx, dy, &d); ! length = hypot(d.x, d.y) * (1 / (float)int2fixed(1)); } dist = length; *************** *** 451,458 **** /* or one of them has zero length. Punt. */ *pi = *pp1; ! #ifdef DEBUG ! if ( gs_debug['o'] ) ! dprintf("\tdegenerate!\n"); ! #endif } else --- 497,501 ---- /* or one of them has zero length. Punt. */ *pi = *pp1; ! if_debug0('o', "\tdegenerate!\n"); } else *************** *** 459,466 **** { pi->x = (fixed)(xnum / denom); pi->y = (fixed)(ynum / denom); ! #ifdef DEBUG ! if ( gs_debug['o'] ) ! dprintf2("\t%f,%f\n", fixed2float(pi->x), fixed2float(pi->y)); ! #endif } } --- 502,507 ---- { pi->x = (fixed)(xnum / denom); pi->y = (fixed)(ynum / denom); ! if_debug2('o', "\t%f,%f\n", ! fixed2float(pi->x), fixed2float(pi->y)); } } *************** *** 472,477 **** /* Draw a line on the device. */ ! private int ! stroke_fill(int first, register pl_ptr plp, pl_ptr nplp, gs_state *pgs) { if ( plp->thin ) { /* Minimum-width line, don't have to be careful. */ --- 513,519 ---- /* Draw a line on the device. */ ! private int near ! stroke_fill(gx_path *ppath, int first, register pl_ptr plp, pl_ptr nplp, ! gs_state *pgs) { if ( plp->thin ) { /* Minimum-width line, don't have to be careful. */ *************** *** 480,484 **** /* slop at the ends. */ fixed dx = litox - lix, dy = litoy - liy; ! #define trsign(v, c) (v >= 0 ? c : -c) #define slop int2fixed(2) fixed xslop = trsign(dx, slop); --- 522,526 ---- /* slop at the ends. */ fixed dx = litox - lix, dy = litoy - liy; ! #define trsign(v, c) ((v) >= 0 ? (c) : -(c)) #define slop int2fixed(2) fixed xslop = trsign(dx, slop); *************** *** 487,492 **** --- 529,536 ---- lix - xslop, liy - yslop, litox + xslop, litoy + yslop) ) + { gp_check_interrupts(); return gz_draw_line_fixed(lix, liy, litox, litoy, pgs->dev_color, pgs); + } #undef slop /* We didn't set up the endpoint parameters before, */ *************** *** 496,500 **** { plp->width.x = plp->e.cdelta.y = 0; plp->width.y = -(plp->e.cdelta.x = ! trsign(dx, float2fixed(-0.5))); } else --- 540,544 ---- { plp->width.x = plp->e.cdelta.y = 0; plp->width.y = -(plp->e.cdelta.x = ! trsign(dx, -fixed_half)); } else *************** *** 501,528 **** { plp->width.y = plp->e.cdelta.x = 0; plp->width.x = -(plp->e.cdelta.y = ! trsign(dy, float2fixed(-0.5))); } #undef trsign - compute_caps(plp); - } - { /* General case. */ - /* Construct a path and hand it to the fill algorithm. */ - if ( stroke_path == 0 ) - { /* We are rendering, and haven't run into the */ - /* general case yet. Initialize the path. */ - stroke_path = &stroke_path_body; /* set global for stroke_add */ - gx_path_init(stroke_path, &pgs->memory_procs); - } - stroke_add(first, plp, nplp, pgs); - { /****** PATCH ******/ - if ( stroke_path == &stroke_path_body ) - { gx_fill_path(stroke_path, pgs->dev_color, pgs, - gx_rule_winding_number, (fixed)0); - gx_path_release(stroke_path); - stroke_path = 0; - } - } } ! return 0; } --- 545,554 ---- { plp->width.y = plp->e.cdelta.x = 0; plp->width.x = -(plp->e.cdelta.y = ! trsign(dy, -fixed_half)); } #undef trsign } ! /* General case: construct a path for the fill algorithm. */ ! return stroke_add(ppath, first, plp, nplp, pgs); } *************** *** 533,545 **** /* Add a segment to the path. This handles all the complex cases. */ ! private int add_capped(P4(gx_path *, gs_line_cap, int (*)(P3(gx_path *, fixed, fixed)), ep_ptr)); ! private int ! stroke_add(int first, register pl_ptr plp, pl_ptr nplp, gs_state *pgs) ! { gx_path *ppath = stroke_path; ! int code; ! if ( ppath == 0 ) return 0; /****** strokepath is NYI ******/ if ( plp->thin ) { /* We didn't set up the endpoint parameters before, */ /* because the line was thin. Do it now. */ compute_caps(plp); } --- 559,571 ---- /* Add a segment to the path. This handles all the complex cases. */ ! private int near add_capped(P4(gx_path *, gs_line_cap, int (*)(P3(gx_path *, fixed, fixed)), ep_ptr)); ! private int near ! stroke_add(gx_path *ppath, int first, register pl_ptr plp, pl_ptr nplp, ! gs_state *pgs) ! { int code; if ( plp->thin ) { /* We didn't set up the endpoint parameters before, */ /* because the line was thin. Do it now. */ + adjust_stroke(plp, pgs); compute_caps(plp); } *************** *** 559,564 **** /* * Set np to whichever of nplp->o.co or .ce ! * is outside the current line. ! * We use the interesting observation that * point (x2,y2) is counter-clockwise from (x1,y1) * relative to the origin iff x1*y2 < x2*y1. --- 585,589 ---- /* * Set np to whichever of nplp->o.co or .ce ! * is outside the current line. We observe that * point (x2,y2) is counter-clockwise from (x1,y1) * relative to the origin iff x1*y2 < x2*y1. *************** *** 578,585 **** else outp = &jp1, np1 = np = &nplp->o.ce, np2 = &plp->e.p; ! #ifdef DEBUG ! if ( gs_debug['o'] ) ! dprintf1("[o]use %s\n", (ccw ? "co (ccw)" : "ce (cw)")); ! #endif /* Don't bother with the miter check if the two */ /* points to be joined are very close together, */ --- 603,607 ---- else outp = &jp1, np1 = np = &nplp->o.ce, np2 = &plp->e.p; ! if_debug1('o', "[o]use %s\n", (ccw ? "co (ccw)" : "ce (cw)")); /* Don't bother with the miter check if the two */ /* points to be joined are very close together, */ *************** *** 628,635 **** ) { /* OK to use a miter join. */ ! #ifdef DEBUG ! if ( gs_debug['o'] ) ! dputs(" ... passes.\n"); ! #endif /* Compute the intersection of */ /* the extended edge lines. */ --- 650,654 ---- ) { /* OK to use a miter join. */ ! if_debug0('o', " ... passes.\n"); /* Compute the intersection of */ /* the extended edge lines. */ *************** *** 653,657 **** /* Compute the endpoints of the two caps of a segment. */ ! private void compute_caps(register pl_ptr plp) { fixed wx2 = plp->width.x; --- 672,676 ---- /* Compute the endpoints of the two caps of a segment. */ ! private void near compute_caps(register pl_ptr plp) { fixed wx2 = plp->width.x; *************** *** 676,680 **** /* Add a properly capped line endpoint to the path. */ /* The first point may require either moveto or lineto. */ ! private int add_capped(gx_path *ppath, gs_line_cap type, int (*add_proc)(P3(gx_path *, fixed, fixed)), /* gx_path_add_point/line */ --- 695,699 ---- /* Add a properly capped line endpoint to the path. */ /* The first point may require either moveto or lineto. */ ! private int near add_capped(gx_path *ppath, gs_line_cap type, int (*add_proc)(P3(gx_path *, fixed, fixed)), /* gx_path_add_point/line */ diff -rc2N gs241/gxtype1.h gs25/gxtype1.h *** gs241/gxtype1.h Sun Mar 29 14:32:24 1992 --- gs25/gxtype1.h Thu May 28 13:23:20 1992 *************** *** 20,99 **** /* gxtype1.h */ /* Private Adobe Type 1 font definitions for GhostScript library */ #include "gstype1.h" ! /* Define the charstring command set */ ! typedef enum { ! c_undef0 = 0, ! c_hstem = 1, ! c_undef2 = 2, ! c_vstem = 3, ! c_vmoveto = 4, ! c_rlineto = 5, ! c_hlineto = 6, ! c_vlineto = 7, ! c_rrcurveto = 8, ! c_closepath = 9, ! c_callsubr = 10, ! c_return = 11, ! c_escape = 12, /* extends the command set */ ! c_hsbw = 13, ! c_endchar = 14, ! c_undoc15 = 15, /* Undocumented by Adobe, */ ! /* but used in some Adobe fonts. */ ! c_undef16 = 16, ! c_undef17 = 17, ! c_undef18 = 18, ! c_undef19 = 19, ! c_undef20 = 20, ! c_rmoveto = 21, ! c_hmoveto = 22, ! c_undef23 = 23, ! c_undef24 = 24, ! c_undef25 = 25, ! c_undef26 = 26, ! c_undef27 = 27, ! c_undef28 = 28, ! c_undef29 = 29, ! c_vhcurveto = 30, ! c_hvcurveto = 31 ! } char_command; ! typedef enum { /* extended commands */ ! ce_dotsection = 0, ! ce_vstem3 = 1, ! ce_hstem3 = 2, ! ce_seac = 6, ! ce_sbw = 7, ! ce_div = 12, ! ce_undoc15 = 15, /* Undocumented by Adobe, */ ! /* but used in some Adobe fonts. */ ! ce_callothersubr = 16, ! ce_pop = 17, ! ce_setcurrentpoint = 33 ! } char_extended_command; ! ! /* Define the encoding of numbers */ ! #define c_num1 32 ! #define c_value_num1(ch) ((int)(byte)(ch) - 139) ! #define c_num2 247 ! #define c_value_num2(c1,c2)\ ! (((int)(byte)((c1) - c_num2) << 8) + (int)(byte)(c2) + 108) ! #define c_num3 251 ! #define c_value_num3(c1,c2)\ ! -(((int)(byte)((c1) - c_num3) << 8) + (int)(byte)(c2) + 108) ! /* Otherwise, the first byte is 255, followed by a 32-bit 2's complement */ ! /* number in big-endian order. */ ! #define c_num4 255 ! ! /* Define the encryption parameters */ ! #define crypt_c1 ((ushort)52845) ! #define crypt_c2 ((ushort)22719) ! #define encrypt_next(ch, state, chvar)\ ! chvar = ((ch) ^ (state >> 8)),\ ! state = (chvar + state) * crypt_c1 + crypt_c2 ! #define decrypt_this(ch, state)\ ! ((ch) ^ (state >> 8)) ! #define decrypt_next(ch, state, chvar)\ ! chvar = decrypt_this(ch, state),\ ! decrypt_skip_next(ch, state) ! #define decrypt_skip_next(ch, state)\ ! state = ((ch) + state) * crypt_c1 + crypt_c2 --- 20,125 ---- /* gxtype1.h */ /* Private Adobe Type 1 font definitions for GhostScript library */ + #include "gscrypt1.h" #include "gstype1.h" ! /* Define the structures for the state of a Type 1 interpreter. */ ! ! /* Define the control state of the interpreter. */ ! /* This is what must be saved and restored */ ! /* when calling a CharString subroutine. */ ! typedef struct { ! const byte *ip; ! crypt_state dstate; ! } ip_state; ! ! /* Define the stem hint tables. */ ! /* Each stem hint table is kept sorted. */ ! /* Stem hints are in device coordinates. */ ! #define max_stems 3 /* arbitrary */ ! typedef struct { ! fixed v0, v1; /* coordinates (widened a little) */ ! fixed dv0, dv1; /* adjustment values */ ! } stem_hint; ! typedef struct { ! int count; ! stem_hint *current; /* cache cursor for search */ ! stem_hint data[max_stems]; ! } stem_hint_table; ! ! /* Define the standard stem width tables. */ ! /* Each table is sorted, since the StemSnap arrays are sorted. */ ! #define max_snaps (1 + max_StemSnap) ! typedef struct { ! int count; ! fixed data[max_snaps]; ! } stem_snap_table; ! ! /* Define the alignment zone structure. */ ! /* These are in device coordinates also. */ ! #define max_a_zones (max_BlueValues + max_OtherBlues) ! typedef struct { ! int is_top_zone; ! fixed v0, v1; /* range for testing */ ! fixed flat; /* flat position */ ! } alignment_zone; ! ! /* Define the structure for hints that depend only on the font and CTM, */ ! /* not on the individual character. Eventually these should be cached */ ! /* with the font/matrix pair. */ ! typedef struct font_hints_s { ! int axes_swapped; /* true if x & y axes interchanged */ ! /* (only set if using hints) */ ! int x_inverted, y_inverted; /* true if axis is inverted */ ! int use_x_hints; /* true if we should use hints */ ! /* for char space x coords (vstem) */ ! int use_y_hints; /* true if we should use hints */ ! /* for char space y coords (hstem) */ ! stem_snap_table snap_h; /* StdHW, StemSnapH */ ! stem_snap_table snap_v; /* StdVW, StemSnapV */ ! fixed blue_fuzz, blue_shift; /* alignment zone parameters */ ! /* in device pixels */ ! int suppress_overshoot; /* (computed from BlueScale) */ ! int a_zone_count; /* # of alignment zones */ ! alignment_zone a_zones[max_a_zones]; /* the alignment zones */ ! } font_hints; ! ! /* This is the full state of the Type 1 interpreter. */ ! #define ostack_size 24 /* per documentation */ ! #define ipstack_size 10 /* per documentation */ ! struct gs_type1_state_s { ! /* The following are set at initialization */ ! gs_show_enum *penum; /* show enumerator */ ! gs_state *pgs; /* graphics state */ ! gs_type1_data *pdata; /* font-specific data */ ! int charpath_flag; /* 0 for show, 1 for false */ ! /* charpath, 2 for true charpath */ ! int paint_type; /* 0/3 for fill, 1/2 for stroke */ ! fixed_coeff fc; /* cached fixed coefficients */ ! float flatness; /* flatness for character curves */ ! font_hints fh; /* font-level hints */ ! /* The following are updated dynamically */ ! fixed ostack[ostack_size]; /* the Type 1 operand stack */ ! int os_count; /* # of occupied stack entries */ ! ip_state ipstack[ipstack_size+1]; /* control stack */ ! int ips_count; /* # of occupied entries */ ! gs_fixed_point lsb; /* left side bearing */ ! gs_fixed_point width; /* character width (char coords) */ ! int seac_base; /* base character code for seac, */ ! /* or -1 */ ! /* The following are set dynamically. */ ! int in_dotsection; /* true if inside dotsection */ ! int vstem3_set; /* true if vstem3 seen */ ! gs_fixed_point vs_offset; /* device space offset for centering */ ! /* middle stem of vstem3 */ ! stem_hint_table hstem_hints; /* horizontal stem hints */ ! stem_hint_table vstem_hints; /* vertical stem hints */ ! }; ! ! /* Interface between main Type 1 interpreter and hint routines. */ ! extern void compute_font_hints(P3(font_hints *, const gs_matrix_fixed *, ! const gs_type1_data *)); ! extern void reset_stem_hints(P1(gs_type1_state *)); ! extern void find_stem_hints(P6(gs_type1_state *, fixed, fixed, ! fixed, fixed, gs_fixed_point *)); ! extern void type1_hstem(P3(gs_type1_state *, fixed, fixed)); ! extern void type1_vstem(P3(gs_type1_state *, fixed, fixed)); diff -rc2N gs241/gzcolor.h gs25/gzcolor.h *** gs241/gzcolor.h Fri Apr 10 15:54:42 1992 --- gs25/gzcolor.h Thu Jul 16 17:56:16 1992 *************** *** 48,53 **** * DeviceGray red, green, blue (all equal) * DeviceRGB red, green, blue ! * DeviceCMYK red, green, blue, not_black * luminance is also used for all of the above. */ /*typedef struct gs_color_s gs_color;*/ /* in gscolor.h */ --- 48,55 ---- * DeviceGray red, green, blue (all equal) * DeviceRGB red, green, blue ! * DeviceCMYK red, green, blue, not_black (not used yet) * luminance is also used for all of the above. + * Note that red, green, and blue are used even for DeviceCMYK; + * this is somewhat bogus and will be fixed when we really implement CMYK. */ /*typedef struct gs_color_s gs_color;*/ /* in gscolor.h */ *************** *** 54,60 **** struct gs_color_s { color_param red, green, blue; /* RGB/~CMY */ ! color_param not_black; /* ~K */ color_param luminance; /* computed luminance */ ! byte /*gs_color_space*/ space; /* see above */ unsigned is_gray : 1; /* quick test for gray */ /* (red==green==blue) */ --- 56,62 ---- struct gs_color_s { color_param red, green, blue; /* RGB/~CMY */ ! color_param not_black; /* ~K (not used yet) */ color_param luminance; /* computed luminance */ ! byte /*gs_color_space_type*/ space; /* see above */ unsigned is_gray : 1; /* quick test for gray */ /* (red==green==blue) */ *************** *** 117,121 **** /* Map a color_param or byte through a transfer map. */ ! extern color_param gx_color_param_map(P2(color_param, color_param *)); #define gx_map_color_param(pgs,cp,m)\ gx_color_param_map(cp, &pgs->transfer->m.values[0]) --- 119,123 ---- /* Map a color_param or byte through a transfer map. */ ! extern color_param gx_color_param_map(P2(color_param, const color_param *)); #define gx_map_color_param(pgs,cp,m)\ gx_color_param_map(cp, &pgs->transfer->m.values[0]) diff -rc2N gs241/gzht.h gs25/gzht.h *** gs241/gzht.h Thu Feb 27 16:14:54 1992 --- gs25/gzht.h Fri Apr 24 19:34:22 1992 *************** *** 28,33 **** int width; int height; struct ht_bit_s *order; /* whitening order */ - int order_size; } halftone_params; --- 28,33 ---- int width; int height; + int order_size; /* = width * height */ struct ht_bit_s *order; /* whitening order */ } halftone_params; diff -rc2N gs241/gzstate.h gs25/gzstate.h *** gs241/gzstate.h Thu Feb 27 16:16:46 1992 --- gs25/gzstate.h Mon Jun 8 01:15:14 1992 *************** *** 1,3 **** ! /* Copyright (C) 1989, 1990, 1991 Aladdin Enterprises. All rights reserved. Distributed by Free Software Foundation, Inc. --- 1,3 ---- ! /* Copyright (C) 1989, 1992 Aladdin Enterprises. All rights reserved. Distributed by Free Software Foundation, Inc. *************** *** 64,66 **** --- 64,69 ---- int device_is_shared; /* true if device is shared, */ /* so don't deallocate at grestore */ + /* Client data: */ + char/*void*/ *client_data; + gs_state_client_procs client_procs; }; diff -rc2N gs241/history.doc gs25/history.doc *** gs241/history.doc Tue Apr 21 04:14:32 1992 --- gs25/history.doc Sat Aug 1 03:05:42 1992 *************** *** 1,3 **** ! Copyright (C) 1989, 1992 Aladdin Enterprises. All rights reserved. Distributed by Free Software Foundation, Inc. --- 1,3 ---- ! Copyright (C) 1992 Aladdin Enterprises. All rights reserved. Distributed by Free Software Foundation, Inc. *************** *** 20,1764 **** - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! This file, history.doc, describes the changes in the various releases of ! Ghostscript. For an overview of Ghostscript and a list of the documentation files, see README. - - Version 2.4.1 (4/21/92) - ============= - - This is a quick release to fix minor problems discovered in 2.4, and - to add a few improvements that didn't quite make it into 2.4. It - also adds GIF and PCX file support. - - Procedures - ---------- - - Fixes bugs: - - Some makefile dependencies, and the ccgs script, caused trouble - for parallel versions of `make'. - - Compiling genarch with -O with gcc on the RS/6000 produced a - buggy executable. - - Fixes some minor problems in make.doc. - - Adds DEVICE_DEVS2..5 to handle long device lists. - - Removes the need to set GS_RUN_EXE when using the Watcom compiler on - MS-DOS systems. - - Gets rid of gs_ccfnt.ps, merging its function into gs_fonts.ps. - - Gets rid of gconfig.ps; this information is now compiled in gconfig.c. - - Utilities - --------- - - Fixes bugs: - - The palette for pstoppm in 8-bit mode didn't contain all 8 - primary colors. - - font2c used just values_ to mean &values_[0]; some compilers - couldn't handle this. - - Makes font2c insert `const' in many appropriate places. - - Drivers - ------- - - Fixes bugs: - - The SunView driver had not been updated properly for 2.4 and was - pretty thoroughly broken. - - None of the printer drivers worked properly with the Watcom - compiler, because stdprn was doing \n -> \r\n substitution. - - If the generic printer driver couldn't allocate the requested - size command list buffer, it gave up rather than trying to allocate a - smaller buffer. - - The SuperVGA drivers (except for the VESA driver) didn't - work with the Watcom compiler, because a couple of places in the - drivers weren't truncating the offset of "segmented" pointers - properly. - - Some of the H-P used *b#Y rather than *p+#Y for - vertical positioning; this apparently is wrong, at least for the - LJIIp. - - Removes the dependence of the X Windows driver on Xt, Xext, and Xmu. As a - result, Ghostscript will not install a standard colormap itself, but it - will use one if one is already installed. - - Adds a set of drivers for Portable Bitmap, Graymap, and Pixmap file - formats. - - Adds drivers for monochrome, EGA/VGA-style, and SuperVGA-style PCX - file formats. - - Adds drivers for monochrome and 256-color GIF file formats. - - Fonts - ----- - - Adds ZapfChancery-MediumItalic as a copy of ZapfChancery-Oblique. - - Interpreter - ----------- - - Fixes bugs: - - A value with l_new set could 'escape' to save level 0 on a - stack; if stored, it prevented the slot from being saved and restored - properly. - - 16#7fffffff + 1 gave the floating point equivalent of -2^31, not - 2^31. - - The PFBDecode filter computed the packet length incorrectly if - the 0x8000-bit of the length was set. - - 5-byte numbers in Type 1 CharStrings complained of a rangecheck - if they exceeded 16 bits, rather than if they exceeded the integer part of - a fixed. - - (, ), and \ appearing in file name arguments in the command - line did not work properly. - - Adds 'const' in many places. - - Changes the random number generator to be the same as the one used in - Level 2 PostScript (as reported by Ed Taft on comp.lang.postscript). - - Exits with code 1 rather than code 0 on an unrecoverable error detected at - the PostScript level. - - Makes dictionaries expand automatically when they fill up. - - Adds gp_exit to complement gp_init. - - Changes dictionaries to always allocate a power of 2 entries on - 32-bit machines. Changes the name table to allocate indices - scattered, so dictionary lookup doesn't have to do a multiply to - scramble the index. - - Changes the handling of currentfile to do "shallow binding" so stack - searching is almost never required. - - Library - ------- - - Fixes bugs: - - arc and arcn got a numeric exception if the radius was zero. - - The undocumented 15 opcode in Type 1 fonts wasn't ignored. - - PaintType 3 wasn't allowed. (It isn't clear what it should - mean; we treat it as equivalent to 0.) - - The VAX/VMS C compiler was generating incorrect code for the - chi_bits and cmask macros in gdevmem, producing incorrect output. - - If the result of the slow algorithm for intersecting clipping - paths was a rectangle, the wrong thing happened (cbox didn't get set). - - gx_path_is_rectangle didn't recognize open rectangles. - - clist_change_tile didn't check properly whether the tile - size had changed, so changing the screen could produce invalid band - files. - - The image operators did the wrong thing in the 1-for-1 - case, interleaving N bytes of data with 7*N bytes of garbage. - - stroke sometimes handled bevel and miter joins wrong in - reflected coordinate systems. - - init_ht checked incorrectly whether there was enough room - to Y-replicate tiles, so sometimes it did it when it shouldn't have. - - stroke sometimes thought lines were thin when they weren't. - - Adds 'const' in many places. - - Adds support for 2- and 4-bit-per-pixel memory devices. - - Version 2.4 (3/25/92) - =========== - - This is a major release that adds SuperVGA support, support for Metrics, - settable device properties, and incremental font loading. It also - includes important performance improvements, based on rewrites of some key - algorithms, and quite a few new Level 2 / Display PostScript facilities. - - Procedures - ---------- - - Fixes bugs: - - The rule for compiling gconfig.c didn't include the -I switches. - - .bat files were being distributed with a \n line terminator - rather than \r\n. - - A CLOSE MODULE_LIST was needed after END_COMPILE: in the VMS - command files. - - Unix systems couldn't handle multiple drivers with overlapping - sets of files. - - -s defined as a null, rather than as an empty string. - - Adds gconfig.ps to the list of needed configuration files. - - Changes the way that the makefile handles nested .h files, so that it - doesn't have to `touch' them. - - Adds the loadallfonts procedure to gs_fonts.ps. - - Changes the standard DOS configuration to include VGA, EGA, VESA, Epson, - BubbleJet, and H-P printer drivers. - - Renames ghost.mak as gs.mak, and gdevs.mak as devs.mak. - - Adds a USE_ASM flag so that one can build a DOS version of Ghostscript - without having an assembler. - - Splits off common code from the two MS-DOS makefiles into tccommon.mak. - - Replaces the COPYING and LICENSE files with a new LICENSE file containing - version 2 of the GNU General Public License. - - Removes DEVICES and DEVICE_OBJS from the makefiles, since they are no - longer needed. - - Adds a GS_DEVICE environment variable to supply a default device name if - desired. - - Adds ansihead.mak and unix-ansi.mak, to parallel [g]cc-head.mak and - unix-[g]cc.mak, for other ANSI C compilers. - - Changes the way that optional features are defined in the makefiles, so - that they actually work. - - Adds support for the Watcom C/386 compiler. - - Allows # in the command line as equivalent to =, to compensate for - brain-damaged MS-DOS shell. - - Adds -sOUTPUTFILE= to set the output file or pipe. - - Adds -dWRITESYSTEMDICT to leave systemdict writable. - - Utilities - --------- - - Fixes bugs: - - pcharstr.ps insisted on having Subrs be present in the font. - - pcharstr.ps decoded negative numbers between -108 and -1131 - incorrectly. - - pfbtogs.ps didn't handle packets longer than 64K correctly. - - Changes the bdftops utility so that it makes entries for UnderlinePosition - and UnderlineThickness in FontInfo, and so that it always records a - FullName (the FontName if no other is provided). - - Changes the name of the pfbtops utility to pfbtogs, because groff already - includes a program called pfbtops. - - Adds the gslp utility for doing "line printing" of text files, similar to - enscript + lpr. - - Adds a new variable DITHERPPI that enables a different dither pattern, - claimed to be better for printers. - - Adds the font2c utility for compiling Type 1 fonts into C, so they can be - linked into an executable rather than loaded dynamically. - - Drivers - ------- - - Fixes bugs: - - gdev_prn_copy_scan_lines was erroneously masking the last byte - of data even on color printers, as was paintjet_print_page. - - The TruFax driver had a couple of compilation errors, since it - hadn't been compiled in a while. - - The BGI driver sometimes didn't consult BGIPATH when looking for - .BGI files. - - initclip did the wrong thing with memory devices. - - The BGI driver didn't look in BGIDIR for .BGI files. - - The Epson driver didn't set the right margin properly with - ESC+Q. - - The BJ-10e driver was badly broken. - - gdev_prn_open/close_printer didn't reset the command list file, - so it was taking quadratic time to print multi-page documents. - - Adds color to the SunView driver. - - Adds selectable resolution (75, 100, 150, or 300 DPI) to the - DeskJet/LaserJet driver. - - Changes gssetdev so that drivers can specify special libraries to be - loaded, as well as object files. - - Adds a driver for VESA-compliant SuperVGA displays. This driver handles - all resolutions from 640 x 400 up to 1280 x 1024, in 256-color mode. The - default is VGA resolution (640 x 480). - - Adds a driver for the ATI Wonder SuperVGA card, and for SuperVGA cards - using the Tseng Labs ET3000 or ET4000 chip such as the STB VGA EM-16 and - the Orchid ProDesigner II (256-color modes only). - - Adds a driver for Trident and Tseng Labs SuperVGA cards in 800 x 600, - 16-color modes (for cards with only 256K of memory). - - Adds user-contributed drivers for the Ricoh 4081, DEC LN03, Canon LBP-8II, - and H-P DeskJet 500C printers. - - Adds Tim Theisen's Ghostview changes to the X11 driver. - - MAKES NON-BACKWARD-COMPATIBLE CHANGES TO THE DRIVER PROCEDURE INTERFACE as - follows: - - - Changes map_rgb_color and map_color_rgb to always work in a - 16-bit color value space, rather than a space defined by the - maximum number of distinct colors provided by the device. - - - Adds an argument to the output_page procedure to indicate - whether the procedure is being called for copypage or - showpage, and a num_copies argument. - - - Adds a gx_bitmap_id to the copy_ and tile_ procedures, so that - drivers can cache bitmaps in the server or device if they want - to. - - - Removes fill_trapezoid and tile_trapezoid. - - - Adds a new get_bits procedure for reading the bits back from the - driver buffer (when possible), replacing copy_scan_lines. - This procedure takes a new argument describing padding and - byte swapping, and returns a different value from - copy_scan_lines. - - - Adds get_props and put_props procedures for accessing arbitrary - additional properties of devices. The interface is quite - complex, but provides a great deal of flexibility. - - See drivers.doc for details. - - Changes gdev_mem_bytes_per_scan_line to gdev_prn_bytes_per_scan_line. - - Adds a user-contributed driver for DigiBoard, Inc.'s fax software. - - Fonts - ----- - - Changes Type1BuildChar so it uses the information from the Metrics - dictionary in the font, if Metrics is present. - - Changes findfont (.loadfont) so it recognizes .PFB fonts and can load them - directly. Also changes .loadfont to disable packing temporarily, because - some fonts rely on procedures being writable (!). - - Interpreter - ----------- - - Fixes bugs: - - The hypot function is not available on some Unix systems. - - Ghostscript didn't flush and close files when exiting. - - In statusdict, the /margins procedure used .leftmargin, but - /setmargins used .lmargin. - - An out-of-range putinterval would simply do nothing, rather than - reporting an error. - - If an attempt to allocate a block larger than the allocator's - chunk size (20K) failed, the allocator would erroneously think it had - succeeded. - - The bind operator made the top-level procedure read-only, as - well as interior procedures. - - gs.c copied 1 extra character for the value of strings defined - on the command line with -s...=, which could smash the first byte of the - next object in memory. - - copying a dictionary erroneously required the maxlength of the - destination to be greater than or equal to the maxlength of the source, - rather than the length of the source. - - undef didn't correctly decide when to mark a deleted entry as - deleted vs. free; as a result, some keys couldn't be looked up properly - after an undef. - - type1encrypt and type1decrypt didn't set the size of the result - properly. - - cvi and cvr didn't allow leading or trailing whitespace in - strings. - - cvs didn't cause an error if the destination string was too - short. - - Many operators didn't check correctly for stack underflow (off - by 1). - - `for' used reals, rather than integers, if the limit was a real, - even if the initial value and increment were integers. - - `restore' didn't properly invalidate copies of the save object - being restored from; `save dup restore restore' would crash. - - `restore' sometimes didn't undo stores into matrices that were - stored into by operators. (The identity matrix always had l_new set.) - - readline gave a rangecheck if the input line exactly filled the - string. - - `--' as the last switch on the command line caused a crash - rather than an error message. - - On MS-DOS systems, filenameforall didn't handle patterns with a - drive or directory specifier properly. - - stroke sometimes called gz_draw_line_fixed even if the line went - outside the clipping box by 1 pixel. - - Changes the loop that binds procedure "operators" to entirely disable the - handling of the typecheck error, rather than to use stopped. This cuts - initialization time significantly, and also eliminates about 35K of wasted - space (for saving the stacks). - - Changes the version "operator" so it returns 47.0. Adds "revision" to - define the Ghostscript version # x 100. - - Adds gscurrentresolution and gssetresolution procedures for getting and - setting the device resolution. - - Adds -r and -rx as command line options for setting - device resolution. - - Adds a facility for incrementally loading the individual CharStrings of a - Ghostscript font from the disk. This can save a lot of memory, at the - expense of slower rendering. (It is intended primarily for MS-DOS - systems.) - - Changes findlibfile to return the name of the file that was actually - opened, as well as the file itself, when the operation succeeds. - - Changes the name of the main entry to the interpreter from interpret to - gs_interpret, because of a conflict with a Data General library procedure. - - Adds the .setmetrics operator to set the metrics for the current - character for Type 1 fonts. - - Adds more LaserWriter-specific entries to statusdict. - - Gives names to all the internal `operators', so they will print out - reasonably when an error occurs. - - Extends the status operator to accept a string and return file - information, as defined for Level 2 PostScript. - - Adds the filter operator and some specific filters: ASCII85Encode, - ASCII85Decode, ASCIIHexEncode, ASCIIHexDecode, eexecDecode, NullEncode, - PFBDecode, and the null case of SubFileDecode. - - Extends the scanner to recognize the Level 2 << and >> tokens. - - Adds a facility for extracting the text strings from a PostScript file and - writing them out in a simple format (selected by -dASCIIOUT, implemented - by gs_2asc.ps). - - Implements all of the remaining Display PostScript facilities that are - also in Level 2 (i.e., everything in section A.1.3 of the PostScript - Language Reference Manual, Second Edition, that is not also in section - A.1.2). The virtual memory operations are all stubs; the new halftone - options are not fully implemented. - - Changes makeimagedevice to use a string of gray or RGB values, rather than - an array of color objects, to specify the palette. Removes - currentgscolor and setgscolor from the interpreter, but leaves t_color - objects in, since they may be useful later. - - Adds getdeviceprops and putdeviceprops for manipulating device properties. - Currently defined properties for all devices: InitialMatrix, HWResolution, - HWSize, Name. Currently defined properties for printers: BufferSpace, - MaxBitmap, OutputFile. OutputFile allows |command for piping on Unix - systems. - - Removes deviceparams and makedevice. Adds devicedefaultmatrix. - - Implements reversepath. - - Makes copy work on devices. - - MS-DOS specific - - - - - - - - - - - Fixes bugs: - - iutilasm.asm wouldn't assemble with newer versions of MASM if - CPU_TYPE was set to 286 or above. - - CPU_TYPE=386 didn't properly substitute the faster - multiply/divide routines under Turbo C++ or Borland C++, only under the - original Turbo C. - - Library - ------- - - Fixes bugs: - - A curve whose first and last points were the same wouldn't get - drawn at all. - - A bug in the Turbo C++ compiler generated bad code when shifting - a long right by 1 bit. - - If stroking a dashed line ever encountered a segment that was - completely blank, Ghostscript would indirect through a null pointer. - - arc and arcn gave an error if the radius was negative. - - stroke always used the general algorithm, even if the line was - guaranteed to be thin. - - arc and arcn erroneously reduced the angles mod 360. - - Very large or negative 32-bit numbers in Type 1 fonts didn't - work properly on MS-DOS systems (the ff0000 bits got set to zero). - - Color printer devices rendering entirely in memory only - allocated a monochrome-sized bitmap. - - clip and eoclip didn't intersect the paths properly in the - general case. - - charpath erroneously rounded the current point to an integral - value, causing characters to be spaced improperly. - - The definition of max_color_param got some compilers confused. - - charpath always used quadratic time and space, and dropped all - but the last character when used with a Type 3 font. - - Stroking a path with a 180 degree angle would incorrectly miter - instead of beveling. - - Type 1 fonts used the current flatness for curves, which could - produce bad (and inconsistent) results. - - Stroking a degenerate line segment produced incorrect results. - - Changes the character cache to use the UniqueID as the key, when - available, instead of the font pointer. This dramatically improves - performance when fonts are getting removed and reloaded because of page - isolation with save/restore. - - Removes some unnecessary casts to (float) from gsmatrix.c and gscoord.c. - - Changes the Type 1 interpreter so that it rounds line and curve endpoints - to the center of the nearest half-pixel, and omits null line segments. - This both speeds up rendering at small sizes and improves output quality. - - Changes gs_deviceparams to return resolution as well as extent; changes - gs_makedevice to accept resolution as well as extent. - - Replaces the algorithm for approximating circular arcs with curves with a - more accurate one. - - Changes gs_point and gs_rect to use doubles rather than floats. - - Adds gs_setmetrics, for overriding Type 1 font metrics for the current - character. - - Changes clipping to use lists of rectangles rather than path intersection. - This makes a big difference when clipping bitmaps (including characters). - - Changes the character cache to discard entries incrementally, rather than - clearing the entire cache when it fills up. - - Changes the implementation of transfer functions to use a cached map, - built when the transfer function is set. This makes transfer functions - work properly in all situations, including images. - - Defines a .quit operator that takes an exit code, and redefines quit in - terms of it. - - Adds support for 16-bit-per-pixel devices in gdevmem. - - Adds gs_copydevice and gs_deviceinitialmatrix; removes gs_deviceparams and - gs_makedevice. - - Changes setscreen to ensure that the cell is always at least 4x4 pixels in - size. - - Version 2.3 (8/28/91) - =========== - - This is a minor release to fix two bugs and add the PaintJet driver, which - didn't make it into 2.2. - - Utilities - --------- - - Changes the pstoppm utility so it counts pages correctly even in the - presence of arbitrary saves and restores. - - Drivers - ------- - - Adds a new, "supported" PaintJet driver. - - Changes the Epson driver to use ESC+D rather than ESC+\ for horizontal - positioning, since many printers don't support the latter. - - Adds horizontal double-density (two-pass) printing to the Epson driver, so - it can do 240 x 60 and 360 x 180 densities. (Vertical double density is - not supported yet.) - - Version 2.2 (6/1/91) - =========== - - The purpose of this release is to add save/restore, and a few - miscellaneous Level 2 P*stScr*pt features such as undef. It also includes - major improvements in graphics quality and in handling of high-resolution - printers. - - Procedures - ---------- - - Changes the version numbering to M.mpp rather than M.m.p, so that - `version' can be a real number for those programs that insist on it. - - Renames ghost.ps as gs_init.ps, gfonts.ps as gs_fonts.ps, and statusd.ps - as gs_statd.ps. The initialization files now all are named gs_*.ps. - - Renames gdevs.{c,h,tl} as gconfig.{c,h,tl}. - - Changes the relevant makefiles and command files so that a single build - can contain several drivers that share code, e.g., the Epson driver and - the DeskJet driver. - - Changes gs_init.ps so it relies on an external gconfig.ps file rather than - making a specific test for the presence of Level 2 features. - - Adds an entry for uglyr.gsf to the makefile. - - Removes the distinction between CCA and CCNA, since most of the files now - contain constructs that require non-ANSI compilation on MS-DOS platforms. - - Adds a `man' page for the ansi2knr utility. - - Changes the documentation (use.doc) to show how to use -sDEVICE=, - or the selectdevice procedure, to select devices by name. - - Adds DEVICE_DEVS to the makefiles (analogous to DEVICES and DEVICE_OBJS). - This finally makes the make procedure fully automatic. - - Adds the name of the initialization file (gs_init.ps) as a - platform-specific makefile parameter, GS_INIT. - - Removes the test program gt.{c,tr} from the fileset, since it is not - useful to users. - - Moves the Symbol encoding vector to a separate file (symbol_e.ps), from - which it is loaded when first used. - - Changes the error handler so it can handle errors that occur while reading - the initialization files. - - Extends ansi2knr so it can handle `void' and `...' in parameter lists. - - Adds quit.ps to the set of installed files. - - MS-DOS-specific changes - - - - - - - - - - - - - - - Adds the VGA and BGI drivers to the standard MS-DOS configuration, and - makes VGA the default. - - Adds a `+' and a newline at the end of gs.tr, to avoid problems with file - transfer programs or editors that add a newline at the end of files. - - Changes the name of msdos.mak to turboc.mak, and creates a new tbcplus.mak - makefile for use with Turbo C++ and Borland C++. - - Changes the extension of the loader response files from .tl to .tr. - - Changes the default search path from c:/ghost and c:/ghost/fonts to c:/gs - and c:/gs/fonts. - - Changes the directory separator from `|' back to ';', since it appears - that DOS can handle a ; in a command line if it is prefixed with \. - - Unix-specific changes - - - - - - - - - - - - - - Changes the uses of install in unixtail.mak so they only install a single - file at a time, which is all that the standard Unix install allows. - - Removes the duplicate files (README/readme, LICENSE/license, - COPYING/copying, Fontmap/fontmap). - - Changes the ld flags from LDPLAT to LDFLAGS. - - Adds XCFLAGS and XLDFLAGS. These are concatenated with CFLAGS and LDFLAGS - respectively. The intention is that they be set from the `make' command - line if desired. - - VMS-specific changes - - - - - - - - - - - - - Repairs the omission of ZPACKED from the VMS build lists. - - Drivers - ------- - - Fixes bugs: - - The SunView driver produced semi-garbage on little-endian - platforms (Sun-386i) because it didn't swap the bit order. - - The X driver would dump core if it couldn't open the display and - the DISPLAY environment variable wasn't set. - - The X driver relied on white = 0, black = ones in a couple of - places; - - The X driver would return an error, instead of clipping, if - asked to display outside the window. - - The X driver would create inappropriately sized windows, because - it believed the server's report of the screen resolution. - - Adds Fran Taylor's Private Eye driver to gdevs.mak and the fileset (not - supported by Aladdin Enterprises). - - Adds Neil Ostroff's TruFax driver to gdevs.mak and the fileset (not - supported by Aladdin Enterprises). - - Makes the scratch file template for the printer drivers a per-platform - quantity (gp_scratch_file_name_template). Puts the default scratch files - for Unix in /usr/tmp rather than /tmp. - - Changes the SunView driver to prevent the Ghostscript window from being - destroyed (which badly confuses the interpreter). - - Extends the Epson driver to handle a variety of print densities in both X - and Y, to handle 24-pin as well as 8-pin graphics, and to allow optional - specification of default density in the makefile (gdevs.mak). - - Refactors the printer drivers so that a single driver handles both DeskJet - and LaserJet. Adds LaserJet drivers that use the new compression modes on - the LJ IId/IIp and LJ III. - - Changes all the printer drivers to use band lists rather than bitmap - paging as the buffering method. (The individual drivers need only a - one-line change to replace mem_copy_scan_lines with - gdev_prn_copy_scan_lines with a different argument.) - - Adds the halftone phase as additional arguments to tile_rectangle and - tile_trapezoid. - - Adds an entirely new and much simpler PaintJet driver, using the new band - list interface. - - Adds margin information to the device structure. This is currently only - relevant for printer devices. - - Adds BGIPATH and BGIUSER environment variables, allowing additional - control of the BGI driver. - - Changes the x/y_pixels_per_inch member of the device structure from int to - float. - - Fonts - ----- - - Patches gs_fonts.ps so definefont will add an isFixedPitch entry to - FontInfo if there isn't one there. - - Removes the old "type 7 path" encoding code from gs_fonts.ps. - - Changes bdftops so it puts isFixedWidth and ItalicAngle entries in the - FontInfo dictionary of the fonts it creates, since some P*stScr*pt - programs rely on this. - - Changes bdftops so it synthesizes as many missing characters as possible - out of the ones that are there (in particular: synthesizes accents out of - punctuation marks, and accented characters using seac.) The results - aren't all that good, but they're a lot better than having characters - missing out of the font. - - Utilities - --------- - - Adds a pfbtops utility for converting .PFB fonts to standard Ghostscript - fonts. - - Fixes bugs: - - ps2image didn't reset things properly between pages for - multi-page documents. - - Interpreter - ----------- - - Makes Ghostscript recognize `-' alone as meaning that it should read from - standard input as though it were a file. This allows Ghostscript to - accept a pipe as input. - - Fixes bugs: - - seac in type1addpath used the current font's encoding, not - StandardEncoding. - - type1decryptfile (eexec) didn't recognize binary (as opposed to - hex) representation. - - Mentioning a name whose value was a no-access object caused an - invalidaccess error. - - There was a bogus definition of `run' in zfile.c. - - The interpreter didn't handle end-of-file on stdin properly. - - Real numbers with an 'e' or 'E' but no decimal point were not - recognized. - - On MS-DOS systems, inside strings, \ followed by a newline was - not discarded properly. - - On MS-DOS systems, the long unsigned divide routine sometimes - gave incorrect answers. Among other things, this caused alternate-radix - numbers sometimes to crash the interpreter. - - cvrs didn't do the right thing about reals or negative integers. - - .echo.mode was being reset with def instead of store, and was - defined in systemdict rather than userdict. - - setgray and settransfer didn't interact properly. - - 16#80000000 was being interpreted as a signed integer (and - converted to a real) rather than an unsigned one. - - atan returned 0 sometimes when it should have returned 180. - - currentcmykcolor was defined wrong. - - Removes the filename operator, since no standard Ghostscript code used it, - and it caused problems with some P*stScr*pt files. - - Implements new operators: filenameforall, selectfont (as a procedure), - stringmatch, undef. - - Adds new standard procedures: selectdevice. - - For MS-DOS, requires that the operand and execution stacks be located in - the data segment, and uses short pointers to address them. This produces - significantly smaller and faster code. (These changes are not visible to - users or library clients.) - - Changes the assignment of attribute bits, and adds new bits for - save/restore and the garbage collector. Changes many of the macros in - store.h to support save/restore. (These changes are not visible to users - or library clients.) Implements save and restore. - - Moves type names from gs_init.ps to ghost.h and ztype.c. - - Moves error names from gs_init.ps to errors.h and iinit.c. - - Introduces gp.h as a documented interface to the platform-specific files. - - Adds the -- switch, which allows Ghostscript programs to take arguments - from the command line. - - Changes many uses of the name `name' to something else, to avoid upsetting - the Microsoft C compiler. - - Really implements packed arrays -- they took the same amount of space as - ordinary arrays in previous versions. - - Changes exitserver in serverdict so that it just clears the stacks. (This - isn't the correct fix, but it will do as a workaround.) - - Makes many miscellaneous small changes to pacify various compilers. - - Changes gs_fonts.ps so that when "quiet" mode is selected (-q switch), - Ghostscript doesn't print anything when loading fonts or when substituting - for undefined characters. - - Defines the name consisting of just a control-D as a no-op, because some - P*stScr*pt-generating applications put control-Ds in their output. - - Implements halftone phase (sethalftonephase and currenthalftonephase - operators). - - Removes the -E switch, since it is no longer useful. - - Changes the -w and -h switches to a single -g (geometry) switch, with - usage -gx. Makes the -h switch, and a new -? switch, print - usage help. - - Implements correct handling of stack overflow errors (makes an array out - of the contents of the overflowing stack, and resets the stack, before - invoking the error handler). - - Adds t_oparray (`operators' defined as procedures) and the makeoperator - operator. This is so that programs like the Distillery that rely on all - operators being bound by `bind' will work properly. - - Adds a new NOPAUSE flag to suppress the prompt and pause at copypage and - showpage. - - Library - ------- - - Fixes bugs: - - gs_type1_interpret didn't store the encryption state or the skip - count before returning to let the client handle a seac or an endchar in - the middle of a seac. - - The definition of the Type 1 operator ce_testadd was based on - wrong information; the operator takes only 2 operands and does something - unknown. - - mem_true24_copy_mono wasn't incrementing the destination pointer - if the color was transparent, leading to garbled characters. - - gx_lookup_fm_pair would sometimes look at one entry beyond the - end of the cached font/matrix pair area. (This probably had no practical - effect.) - - gs_type1_interpret didn't save the current point when returning - to the client for a callothersubr, causing some characters to be rendered - displaced (such as some of the chess pieces in chess.ps). - - gs_setgray, gs_sethsbcolor, gs_setrgbcolor, gs_setflat, and - gs_setlinewidth gave errors for out-of-range operands rather than forcing - them into range. - - Transfer functions were not actually supported. - - The area fill algorithm failed on certain complex paths. - - The current point was sometimes defined when a BuildChar - procedure was called. - - Stroking a degenerate line didn't display anything for round - caps or joins. - - If the ends of a curve had exactly the same X coordinate, the - curve sometimes wouldn't be displayed. - - Very thin lines that went outside the clipping region would - sometimes be displayed as dashed, or not at all. - - The translation in a FontMatrix was ignored. - - Very wide, shallow lines would color extraneous pixels when - using bevel or miter joins. - - Dashed lines didn't join properly at the beginning of a closed - path. - - 0-degree arcs didn't add the appropriate line (possibly - degenerate) to the path. - - gs_type1_interpret didn't reset the callsubr stack when starting - the base character of a seac, which caused confusion if the accent's - endchar fell inside a Subr. - - Non-monochrome memory memory devices weren't checking the - arguments of the drawing procedures properly. - - The initial clipping rectangle for memory devices was being - computed wrong. - - Null devices had a semi-infinite clipping rectangle instead of - an empty one. - - gs_setlinewidth was treating negative arguments as zero, instead - of taking the absolute value. - - imagemask with a dithered color used a solid color rather than - the dithered one. - - Tweaks the area fill and image rendering algorithms to be a little more - liberal with paint when being used to render characters. - - Changes the name of the 8-bit mapped color memory device from - mem_mapped_color_device to mem_mapped8_color_device. - - Changes the memory devices so that on little-endian platforms, they can - store the bytes within a word in either order. (Little-endian order - allows efficient 32-bit updating, big-endian is required when displaying - or writing to a printer or a file.) - - Implements halftone phase. - - Replaces the trapezoid fill algorithm with a much more accurate one - inspired by a contribution from Paul Haeberli. This also changes the - graphics convention back to filling only pixels whose center falls within - the region to be filled. - - Changes the character cache to allocate headers and bits contiguously out - of a single ring buffer. - - Changes gs_imagemask and gs_imagemask_init to take a thickness adjustment - parameter. - - Changes gs_setcachedevice and gs_setcharwidth to take the graphics state - as a parameter. - - Renames gx_device_memory_bitmap_size as gdev_mem_bitmap_size, - mem_copy_scan_lines as gdev_mem_copy_scan_lines, and - mem_bytes_per_scan_line as gdev_mem_bytes_per_scan_line. - - Version 2.1.1 (1/15/91) - ============= - - This is a sub-release distributed to fix a few early bugs in 2.1, just in - time for the new GNU master tape. - - Build procedures - ---------------- - - Removes all of the (undebugged) Level 2 code from the fileset, as well as - the (unused) file gdevvga.c. - - Changes the tar file so that the files are stored in the directory - gs rather than simply gs, e.g., gs211. - - Interpreter - ----------- - - Changes the scanner so that \ is recognized within strings regardless of - whether the scanner is reading from a string or from a file. This is - compatible with newer P*stScr*pt interpreters, and with the newer - P*stSc*pt language specification, but not with the older specification in - the original PostScript Language Reference Manual. - - Drivers - ------- - - Fixes the max_value macro in gdevmem.c so that compilers won't complain - about a left shift by 32. - - Adds 'byte' to the list of types that gdevx.c must sidestep because header - files use them. - - Library - ------- - - Changes the computation of penum->unpack in gsimage.c so as not to upset - compilers that don't treat procedures and pointers to procedures as - compatible types for conditional expressions. - - Version 2.1 (12/31/90) - =========== - - This is primarily a bug fix release to clean up problems in 2.0. It also - implements a first cut at the new color operators. - - Build procedures - ---------------- - - Changes the separator for multiple directories in MS-DOS from ';' to '|', - since there is no way to include a ';' in a command line. - - Adds /fonts to the default search path, where is c:/ghost for - MS-DOS systems and `pwd` for Unix systems. - - Adds new documentation describing how to direct output to the printer. - - Changes the PROCTYPE and USE8087 options in MSDOS.MAK to CPU_TYPE and - FPU_TYPE. The latter now indicates the type of FPU to generate code for, - if any. - - Drivers - ------- - - Adds a driver for the Canon BubbleJet BJ10e. - - Modifies the EGA driver to handle (non-standard) frame buffers larger than - 64K. Adds drivers for the VGA and for the EIZO MDB-10 (a 1024 x 768 frame - buffer). - - Changes the X driver so that it clips to the window dimensions, rather - than reporting an error. - - Notes that the H-P LaserJet driver, like the DeskJet driver, works under - Unix as well as MS-DOS. - - Adds support for 120 X DPI mode, and for the LQ-1500, to the Epson driver. - - Fonts - ----- - - Fixes bugs in bdftops: - - It was using /UniqueId instead of /UniqueID as the key for the - font unique ID. This effectively disabled the font cache. - - The definition for .notdef was bogus -- an invalid CharString. - - Changes ghost.ps and gfonts.ps so that NullFont is the initial font, - rather than Ugly. - - Arranges things so that when attempting a font substitution, if the - default font is not found, NullFont is used instead. - - Extends bdftops so that if certain easily synthesized characters are - missing from a font, it will attempt to synthesize them using available - characters. - - Interpreter - ----------- - - Extends the -T switch to allow specifying a printf template for the - arguments of the procedure being traced. - - Fixes bugs: - - /0 was interpreted as equivalent to 0 (a number) rather than a - literal name. - - packedarray was defined as being like array, instead of like - array followed by astore. - - Many minor and harmless type mismatches (and a couple of very - minor genuine bugs) were upsetting the Apollo C compiler. - - exp was incorrectly failing in certain cases with a negative - first argument. - - copyscanlines incorrectly required at least 4 elements on the - operand stack, although it correctly only used the top 3. - - readhexstring incorrectly read 1 byte even if the string length - was zero. - - Not every place that expected an array would accept a packed - array. - - Very complex paths (and infrequently other things) could produce - a 'memory leak'. - - / alone would skip following whitespace and gather following - characters, rather than creating an empty name. - - ghost.ps left newerror defined as true in $error, which resulted - in an erroneous error report if a program executed a 'stop'. - - The definition of exitserver in serverdict didn't clear the - stack. - - currentfile returned an executable file, rather than a literal - one. - - setfont for Type 1 fonts didn't check the UniqueID in the font - dictionary against the one in the font's Private dictionary. - - A value stored in a dictionary under the key /xxx couldn't be - retrieved using the key (xxx), and vice versa. - - charpath with a Type 1 font on a string containing a 'space' - would produce garbage (it released the parent path inappropriately). - - bytesavailable did not work properly for terminal input. - - Changes the interface to the memory allocator so that it always takes an - element size and an element count, like calloc instead of malloc (but note - that alloc does *not* clear just-allocated blocks). Gets rid of the - special 'dynamic' allocation procedures. - - Changes the random number operators to use a better implementation. - - Changes the idiv operator so it will accept any numbers, not just - integers, as arguments. (The PostScript manual doesn't allow this, but - implementations apparently do.) - - Provides semi-fake but usable definitions for all of the color PostScript - extensions, including a real implementation of colorimage. - - No longer uses the name 'null', which is apparently reserved by Microsoft - C. Makes a number of other minor changes required to pacify the Microsoft - C compiler. - - Implements %statementedit and %lineedit. (%statementedit is equivalent to - %lineedit, which is wrong.) Changes the interactive interpreter to use - %statementedit. - - Changes the scanner to accept null, ctrl-K (vertical tab), and ctrl-L - (form feed) as whitespace. Ctrl-L terminates a comment, null and ctrl-K - do not. - - Allows a literal string as the 'proc' argument(s) for image, imagemask, - and colorimage. - - Adds the following operators/procedures: arct, cleardictstack, deletefile, - renamefile. - - Defines =print as a synonym for =, for the benefit of LaserPrep. - - Implements non-zero PaintType for the show operators (but not for - charpath) for Type 1 fonts. - - Adds the ISOLatin1Encoding encoding vector. - - Renames currentcolor and setcolor as currentgscolor and setgscolor, to - avoid conflict with the Level 2 PostScript names. Removes colorhsb, - colorrgb, hsbcolor, and rgbcolor. - - Library - ------- - - Fixes bugs: - - In a couple of places, a 0 was being passed as a pointer - argument without casting, which confused the Microsoft C compiler. - - Image devices were not recognized properly in debugging - configurations. - - Inverted-color monochrome image devices were not recognized - properly. - - Images that exactly fill the drawing area rendered very slowly, - because they erroneously used the general clipping algorithm. - - Images that are 1-for-1 with the device were incorrectly scaled - by a factor of 8 in X. - - Rounding artifacts sometimes caused characters to be unevenly - offset vertically by 1 pixel. - - Type 1 fonts that used the Flex feature resulted in garbled - images. - - The show operator routines would incorrectly fill or stroke a - path that existed at the time the show was started. - - setscreen truncated the cell size instead of rounding, which - could produce off-by-1 anomalies. - - stroke would sometimes produce garbage (or nothing at all) for - very narrow lines. - - path filling would only color the pixels whose centers fell - inside the path: the Adobe specification requires coloring a pixel if any - part of it falls inside the path. - - Changes the Epson printer driver so that it drives the printer directly - rather than writing to a file. - - Changes pathbbox so that if the path is empty but there is a current - point, it returns a null rectangle at the current point. - - Changes gs_image_init to take an additional parameter (after bps) giving - the number of samples per pixel (1, 3, or 4), and an indication of whether - the samples for each pixel are together or separated (-3 or -4). - - Renames the gs_image_data and gs_imagemask_data procedures as gs_image and - gs_imagemask, and removes the old versions of the latter. - - Adds gs_colorimage. - - Replaces Snoopy's color dithering algorithm with one contributed by Paul - Haeberli. - - Changes gs_setgray, gs_[set]hsbcolor, and gs_[set]rgbcolor so that they - coerce arguments outside the range [0..1] back into the range, instead of - signalling an error. - - Makes a number of minor changes required to pacify the Microsoft C - compiler. - - Changes gs_arcto so that if the last argument is a null pointer, the - tangent points are not returned. - - Removes gs_type1addpath, which is not useful. (Clients must call - gs_type1_init and gs_type1_interpret directly.) - - Implements the 'seac' opcode for Type 1 fonts, allowing fonts with accented - characters to display properly. - - Implements the undocumented 'testadd' opcode for Type 1 fonts, which is - used by some Adobe fonts. - - Renames gs_currentcolor and gs_setcolor as gs_currentgscolor and - gs_setgscolor. Removes gs_colorhsb, gs_colorrgb, gs_hsbcolor, and - gs_rgbcolor. - - Version 2.0 (9/12/90) - =========== - - The main purpose of this release is to add fonts, support for multiple - devices, and imaging into memory. It also fixes a number of miscellaneous - bugs. (Unfortunately, accurate records of the bugs fixed are not - available.) The changes were so extensive that we chose to increment the - major version number. - - Miscellaneous - ------------- - - Doesn't attempt to open the .MAP file on Unix systems. - - Adds mention of statusd.ps to interp.doc. - - Notes that Turbo C 2.0, not 1.5, is required for building the MS-DOS - version. - - Adds a DEVICES= line to the makefile, and allows multiple devices. - - Documents, in interp.doc, the X Windows resources that Ghostscript - recognizes. - - Adds three PostScript masters to the fileset: chess.ps (+ cheq.ps), - golfer.ps, and escher.ps. - - Drivers - ------- - - Changes the names of all the device drivers. See gdevs.mak for the - updated list. - - Adds a (working) driver for SunView. - - Adds drivers for the Sony NeWS frame buffer, and the Sony Microsystems - NWP533 printers. These drivers were contributed by users, so we aren't - prepared to answer questions about them. - - Adds a driver for the Borland Graphics Interface (BGI) for MS-DOS systems. - Note that to use this driver with a non-EGA/VGA display, you need a .BGI - file appropriate for your hardware. (The Ghostscript executable includes - the EGA/VGA driver.) - - Adds a driver for Epson printers. The driver has only been tested on an - LX-800, and on an H-P DeskJet in FX-80 emulation mode, but may work on - other models. The driver could be adapted to work on Unix systems, but as - distributed, it only works on MS-DOS systems. - - Adds a driver for the Hewlett-Packard DeskJet printer. The driver could - be adapted to work on Unix systems, but as distributed, it only works on - MS-DOS systems. - - The X Windows driver no longer waits for the user to type a character - before bringing up the initial display. - - Adds information to drivers.doc describing how to change the definition of - the device structure and procedure table. - - Extends the tile_rectangle and tile_trapezoid driver procedures to - interpret color0 = color1 = gx_no_color_index as meaning that the tile is - actually colored, not a mask. - - Build procedures - ---------------- - - Changes the tar file so it puts everything in a directory called gs. - - Removes the -ansi switch for gcc (this was causing problems with - on some systems). - - Changes LDPLAT to the string -X, which is appropriate for most Unix - systems (but not for SunOS 4.n). - - Adds EXTRALIBS to the makefile, for specifying additional libraries to be - linked in. - - Adds a 'clean' target for 'make', to get rid of all temporary files, the - binaries, and the executable. - - Changes names of system-specific files from gp-xxx.c to gp_xxx.c. - - Adds support for VMS (gp_vms.c and ghost.dcl). - - Creates a new file gdevs.mak, and reorganizes the other makefiles, so that - the choice of which device driver(s) to include is isolated in a single - line in the platform-specific makefile. - - Changes the standard MS-DOS makefile so it builds for 8088/86 (not 80386), - with neither -DNOPRIVATE nor -DDEBUG. - - Changes the name of the MS-DOS makefile from dos-ega.mak to msdos.mak, and - the Unix makefiles from ux-[g]cc-x.mak to unix-[g]cc.mak. - - Updates drivers.doc to describe how to add new drivers in gdevs.mak. - - Removes gdevs.ps: the drivers are now responsible for specifying the size - of the imaging region. - - Interpreter - ----------- - - Adds a makefile macro GS_LIB_DEFAULT and an environment variable GS_LIB to - define a search path for the library (initialization and font) files, and - implements the -I switch for the same purpose (replacing -sLIB=, which was - never actually implemented). See interp.doc for details. - - No longer clears the operand stack between interactive inputs. No longer - prints the contents of the operand stack after every input in debug mode. - - Doesn't "eat" the character that the user types to proceed after a - showpage, unless it's an isolated . - - Changes the prompt so that it says - GS> - if the operand stack is empty, or - GS - if there are n > 0 elements on the operand stack. - - Adds -w and -h switches to the command line, equivalent to -dWIDTH= and - -dHEIGHT= except that they require numeric arguments. - - Adds -q (quiet startup) switch to the command line, which suppresses some - initial messages and also has an effect equivalent to -dQUIET. - - Fixes bugs: - - = and == caused an error on some kinds of objects if the object - didn't have read access. - - cvs didn't print operator names. - - The definition of dynamic_begin in iscan.c caused the DEC VMS C - compiler to produce incorrect code. - - mul didn't return a correct (real) result when multiplying a - very large integer by an integer that wasn't very large. - - eq and ne didn't work on files, fonts, save objects, and some - operators. - - The scanner would sometimes blow up on floating point numbers - beginning with a '.'. - - flushfile didn't pop its argument from the stack. - - put and putinterval would store into a packed array. - - a few operators didn't check properly for stack underflow. - - cvrs produced wrong output for radix values greater than 10. - - The scanner would convert upper-case letters in alternate-radix - numbers wrong on Unix systems. - - String comparisons other than equality often produced the wrong - result if the strings were of different lengths. - - An ifelse as the last thing inside a forall would confuse the - execution stack. - - There were some omitted casts and 'private' declarations that - made the GNU compiler unhappy. - - There was a memory leak in the image[mask] operators that caused - 516 bytes to be permanently lost each time one of them was used. - - Quoted strings of length greater than 50 and less than 100 would - get mangled when being read in. - - The scanner didn't consume the whitespace character following a - token, so programs that read data out of the program file could get - confused. - - Under rare circumstances, an object of size between 249 and 255 - bytes could get allocated on top of another object. - - Allows bind to bind packed arrays, even though they aren't normally - writable. - - Changes the length operator to allow a name as the argument. (The - PostScript manual doesn't allow this, but implementations apparently do.) - - Changes the setcachedevice operator to allow the bounding box to be - specified as a 4-element array instead of 4 scalars. (The PostScript - manual doesn't allow this, but implementations apparently do.) - - Removes a line from ghost.ps that accidentally disabled the font cache. - - Implements memory devices (makeimagedevice, copyscanlines, and makedevice - for image devices). makeimagedevice is implemented only for 1, 8, 24, and - 32 bits per pixel. - - Changes the deviceparams operator so it pushes a mark on the stack below - the parameters. This is to allow for devices that have more than the - standard set of parameters. - - Replaces defaultdevicename with two new operators, getdevice and - devicename. - - Adds a flushpage operator that flushes any outstanding buffered output to - the screen. This is not the same as copypage: on printers, copypage - actually prints a page, whereas flushpage may do nothing; on displays, - flushpage and copypage may both flush output to a server. - - Adds an unread operator for pushing back a character into a file. - - Adds a description of proposed grayimage and colorimage operators to - ghost.doc, even though they aren't implemented yet. - - Changes the name of the currentfileposition operator to fileposition. - - Removes the framedevice operator, since the new device operators supersede - it. - - Adds a writeppmfile operator, for writing the contents of a memory device - to a ppm file. - - Makes Ghostscript work even when the >> operator doesn't sign-extend - negative numbers. (This has not been tested.) - - Adds the Symbol encoding to ghost.ps. - - Adds two new file-related operators, filename and findlibfile. See - ghost.doc and interp.doc for details. - - Adds type1encrypt and type1decrypt operators for manipulating Adobe Type 1 - encoded fonts. - - Changes the imagecharpath and addcharpath operators to type1imagepath and - type1addpath. These operators now work with the Adobe Type 1 font - encoding. - - Adds the type1decryptfile operator for reading Adobe Type 1 encrypted - fonts. - - Library - ------- - - Fixes bugs: - - curveto and lineto didn't check for the current point being - defined. - - stringwidth would fail if there was no current point. - - There were om