summaryrefslogtreecommitdiff
path: root/render
diff options
context:
space:
mode:
Diffstat (limited to 'render')
-rw-r--r--render/Jamfile31
-rw-r--r--render/License.txt662
-rw-r--r--render/Makefile.am13
-rw-r--r--render/Readme.txt10
-rw-r--r--render/afiles11
-rw-r--r--render/makecharts.ksh12
-rw-r--r--render/render.c2425
-rw-r--r--render/render.h239
-rw-r--r--render/screens.h811
-rw-r--r--render/thscreen.c474
-rw-r--r--render/thscreen.h156
-rw-r--r--render/timage.c682
12 files changed, 5526 insertions, 0 deletions
diff --git a/render/Jamfile b/render/Jamfile
new file mode 100644
index 0000000..fe975ea
--- /dev/null
+++ b/render/Jamfile
@@ -0,0 +1,31 @@
+
+# Optimization and Debug flags
+
+#PREF_CCFLAGS += $(CCOPTFLAG) ; # Turn optimisation on
+PREF_CCFLAGS += $(CCDEBUGFLAG) ; # Debugging flags
+#PREF_CCFLAGS += $(CCHEAPDEBUG) ; # Heap Debugging flags
+PREF_LINKFLAGS += $(LINKDEBUGFLAG) ; # Link with debug info
+#PREF_CCFLAGS += $(CCPROFFLAG) ; # Profile flags
+#PREF_LINKFLAGS += $(LINKPROFFLAG) ; # Profile flags
+
+#Products
+Libraries = librender ;
+Executables = timage ;
+Headers = render.h ;
+
+#Install
+InstallBin $(DESTDIR)$(PREFIX)/bin : $(Executables) ;
+#InstallFile $(DESTDIR)$(PREFIX)/h : $(Headers) ;
+#InstallLib $(DESTDIR)$(PREFIX)/lib : $(Libraries) ;
+
+HDRS = ../h ../numlib $(TIFFINC) ;
+
+# 2D Rendering library
+Library librender : render.c thscreen.c ;
+
+Main timage : timage.c : : : : : librender ../numlib/libnum $(TIFFLIB) $(JPEGLIB) ;
+
+
+if $(BUILD_JUNK) {
+ Main tt : tt.c : : : ../plot : : ../numlib/libnum ../plot/libplot ;
+}
diff --git a/render/License.txt b/render/License.txt
new file mode 100644
index 0000000..a871fcf
--- /dev/null
+++ b/render/License.txt
@@ -0,0 +1,662 @@
+ GNU AFFERO GENERAL PUBLIC LICENSE
+ Version 3, 19 November 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU Affero General Public License is a free, copyleft license for
+software and other kinds of works, specifically designed to ensure
+cooperation with the community in the case of network server software.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+our General Public Licenses are intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ Developers that use our General Public Licenses protect your rights
+with two steps: (1) assert copyright on the software, and (2) offer
+you this License which gives you legal permission to copy, distribute
+and/or modify the software.
+
+ A secondary benefit of defending all users' freedom is that
+improvements made in alternate versions of the program, if they
+receive widespread use, become available for other developers to
+incorporate. Many developers of free software are heartened and
+encouraged by the resulting cooperation. However, in the case of
+software used on network servers, this result may fail to come about.
+The GNU General Public License permits making a modified version and
+letting the public access it on a server without ever releasing its
+source code to the public.
+
+ The GNU Affero General Public License is designed specifically to
+ensure that, in such cases, the modified source code becomes available
+to the community. It requires the operator of a network server to
+provide the source code of the modified version running there to the
+users of that server. Therefore, public use of a modified version, on
+a publicly accessible server, gives the public access to the source
+code of the modified version.
+
+ An older license, called the Affero General Public License and
+published by Affero, was designed to accomplish similar goals. This is
+a different license, not a version of the Affero GPL, but Affero has
+released a new version of the Affero GPL which permits relicensing under
+this license.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU Affero General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Remote Network Interaction; Use with the GNU General Public License.
+
+ Notwithstanding any other provision of this License, if you modify the
+Program, your modified version must prominently offer all users
+interacting with it remotely through a computer network (if your version
+supports such interaction) an opportunity to receive the Corresponding
+Source of your version by providing access to the Corresponding Source
+from a network server at no charge, through some standard or customary
+means of facilitating copying of software. This Corresponding Source
+shall include the Corresponding Source for any work covered by version 3
+of the GNU General Public License that is incorporated pursuant to the
+following paragraph.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the work with which it is combined will remain governed by version
+3 of the GNU General Public License.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU Affero General Public License from time to time. Such new versions
+will be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU Affero General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU Affero General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU Affero General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If your software can interact with users remotely through a computer
+network, you should also make sure that it provides a way for users to
+get its source. For example, if your program is a web application, its
+interface could display a "Source" link that leads users to an archive
+of the code. There are many ways you could offer source, and different
+solutions will be better for different programs; see section 13 for the
+specific requirements.
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU AGPL, see
+<http://www.gnu.org/licenses/>.
+
diff --git a/render/Makefile.am b/render/Makefile.am
new file mode 100644
index 0000000..2f88d0f
--- /dev/null
+++ b/render/Makefile.am
@@ -0,0 +1,13 @@
+include $(top_srcdir)/Makefile.shared
+
+privatelib_LTLIBRARIES = librender.la
+privatelibdir = $(pkglibdir)
+
+librender_la_SOURCES = render.h render.c thscreen.h thscreen.c
+librender_la_LIBADD = $(TIFF_LIBS) ../numlib/libargyllnum.la
+
+LDADD = ./librender.la ../numlib/libargyllnum.la $(TIFF_LIBS)
+
+check_PROGRAMS = timage
+
+EXTRA_DIST = License.txt Readme.txt
diff --git a/render/Readme.txt b/render/Readme.txt
new file mode 100644
index 0000000..6ed3ea7
--- /dev/null
+++ b/render/Readme.txt
@@ -0,0 +1,10 @@
+
+2D Raster rendering support.
+---------------------------
+
+This is a very simple 2D rendering library, intended to
+support test and verification chart generation, and
+raster color test chart creation. Speed is not
+an objective of this library, just simplicity.
+
+
diff --git a/render/afiles b/render/afiles
new file mode 100644
index 0000000..26a7384
--- /dev/null
+++ b/render/afiles
@@ -0,0 +1,11 @@
+Readme.txt
+License.txt
+afiles
+Jamfile
+makecharts.ksh
+render.h
+render.c
+timage.c
+thscreen.h
+thscreen.c
+screens.h
diff --git a/render/makecharts.ksh b/render/makecharts.ksh
new file mode 100644
index 0000000..98ceb11
--- /dev/null
+++ b/render/makecharts.ksh
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+# create some gamut mapping test charts
+./timage cube.tif
+./timage -x cube16.tif
+./timage -g 20 cubeG20.tif
+./timage -g 50 cubeG50.tif
+./timage -4 cmykcube.tif
+./timage -t -s surface.tif
+./timage -t -s -x surface16.tif
+./timage -t -s -g 20 surfaceG20.tif
+./timage -t -s -g 50 surfaceG50.tif
diff --git a/render/render.c b/render/render.c
new file mode 100644
index 0000000..cbeb78d
--- /dev/null
+++ b/render/render.c
@@ -0,0 +1,2425 @@
+
+/*
+ * render2d
+ *
+ * Simple 2D raster rendering support.
+ *
+ * Author: Graeme W. Gill
+ * Date: 28/12/2005
+ *
+ * Copyright 2005, 2008, 2012 Graeme W. Gill
+ * All rights reserved.
+ *
+ * This material is licenced under the GNU AFFERO GENERAL PUBLIC LICENSE Version 3 :-
+ * see the License.txt file for licencing details.
+ */
+
+#undef DEBUG
+
+#define verbo stdout
+
+#include <stdio.h>
+#include <math.h>
+#include <stdlib.h>
+#include "copyright.h"
+#include "aconfig.h"
+#include "sort.h"
+#include "numlib.h"
+#include "tiffio.h"
+#include "render.h"
+#include "thscreen.h"
+
+/* ------------------------------------------------------------- */
+/* Utilities */
+
+/* Standard L*a*b* to TIFF 8 bit CIELAB */
+static void cvt_Lab_to_CIELAB8(double *out, double *in) {
+ out[0] = in[0];
+ if (out[0] < 0.0)
+ out[0] = 0.0;
+ else if (out[0] > 100.0)
+ out[0] = 100.0;
+ out[0] = out[0] / 100.0 * 255.0;
+
+ out[1] = in[1];
+ if (out[1] < -128.0)
+ out[1] = -128.0;
+ else if (out[1] > 127.0)
+ out[1] = 127.0;
+ if (out[1] < 0.0)
+ out[1] = 256.0 + out[1];
+
+ out[2] = in[2];
+ if (out[2] < -128.0)
+ out[2] = -128.0;
+ else if (out[2] > 127.0)
+ out[2] = 127.0;
+ if (out[2] < 0.0)
+ out[2] = 256.0 + out[2];
+}
+
+/* Standard L*a*b* to TIFF 16 bit CIELAB */
+static void cvt_Lab_to_CIELAB16(double *out, double *in) {
+ out[0] = in[0];
+ if (out[0] < 0.0)
+ out[0] = 0.0;
+ else if (out[0] > 100.0)
+ out[0] = 100.0;
+ out[0] = out[0] / 100.0 * 65535.0;
+
+ out[1] = in[1];
+ if (out[1] < -32768.0)
+ out[1] = -32768.0;
+ else if (out[1] > 32767.0)
+ out[1] = 32767.0;
+ if (out[1] < 0.0)
+ out[1] = 65536.0 + out[1];
+
+ out[2] = in[2];
+ if (out[2] < -32768.0)
+ out[2] = -32768.0;
+ else if (out[2] > 32767.0)
+ out[2] = 32767.0;
+ if (out[2] < 0.0)
+ out[2] = 65536.0 + out[2];
+}
+
+/* ------------------------------------------------------------- */
+/* Main class implementation */
+
+/* Free ourselves and all primitives */
+static void render2d_del(render2d *s) {
+ prim2d *th, *nx;
+
+ /* Delete all the primitives */
+ for (th = s->head; th != NULL; th = nx) {
+ nx = th->next;
+ th->del(th);
+ }
+
+ /* And then ourselves */
+ free(s);
+}
+
+/* Add a primitive */
+static void render2d_add(render2d *s, prim2d *p) {
+ if (p == NULL)
+ error("render2d: Adding NULL primitive");
+
+ p->next = s->head;
+ s->head = p;
+ p->ix = s->ix;
+ s->ix++;
+}
+
+/* Set the default color */
+static void render2d_set_defc(render2d *s, color2d c) {
+ int j;
+
+ for (j = 0; j < s->ncc; j++)
+ s->defc[j] = c[j];
+ s->defc[PRIX2D] = c[PRIX2D];
+}
+
+
+/* Set background color function */
+static void render2d_set_bg_func(render2d *s,
+ void (*func)(void *cntx, color2d c, double x, double y),
+ void *cntx
+) {
+ s->bgfunc = func;
+ s->cntx = cntx;
+}
+
+/* Compute the length of a double nul terminated string, including */
+/* the nuls. */
+static int zzstrlen(char *s) {
+ int i;
+ for (i = 0;; i++) {
+ if (s[i] == '\000' && s[i+1] == '\000')
+ return i+2;
+ }
+ return 0;
+}
+
+/* Decide whether a color is different enough to need anti-aliasing */
+static int colordiff(render2d *s, color2d c1, color2d c2) {
+ int j;
+
+ for (j = 0; j < s->ncc; j++) {
+ if (fabs(c1[j] - c2[j]) > 1e-5)
+ return 1;
+ }
+ return 0;
+}
+
+#define MIXPOW 1.3
+#define OSAMLS 16
+
+/* Render and write to a TIFF file */
+/* Return NZ on error */
+static int render2d_write(render2d *s, char *filename, int comprn) {
+ TIFF *wh = NULL;
+ uint16 samplesperpixel = 0, bitspersample = 0;
+ uint16 extrasamples = 0; /* Extra "alpha" samples */
+ uint16 extrainfo[MXCH2D]; /* Info about extra samples */
+ uint16 photometric = 0;
+ uint16 inkset = 0xffff;
+ char *inknames = NULL;
+ tdata_t *outbuf;
+ unsigned char *tempbuf = NULL; /* 16 bit buffer for dithering */
+ thscreens *screen = NULL; /* dithering object */
+ prim2d *th, **pthp;
+ prim2d **xlist, **ylist; /* X, Y sorted start lists */
+ int xli, yli; /* Indexes into X, Y list */
+ int noix; /* Number in x list */
+ color2d *pixv0, *_pixv0; /* Storage for pixel values around current */
+ color2d *pixv1, *_pixv1;
+ sobol *so; /* Random sampler for anti-aliasing */
+ int i, j;
+
+ double rx0, rx1, ry0, ry1; /* Box being processed, newest sample is rx1, ry1 */
+ int x, y; /* Pixel x & y index */
+
+ if ((so = new_sobol(2)) == NULL)
+ return 1;
+
+ switch (s->csp) {
+ case w_2d: /* Video style grey */
+ samplesperpixel = 1;
+ photometric = PHOTOMETRIC_MINISBLACK;
+ break;
+ case k_2d: /* Printing style grey */
+ samplesperpixel = 1;
+ photometric = PHOTOMETRIC_MINISWHITE;
+ break;
+ case lab_2d: /* TIFF CIE L*a*b* */
+ samplesperpixel = 3;
+ photometric = PHOTOMETRIC_CIELAB;
+ break;
+ case rgb_2d: /* RGB */
+ samplesperpixel = 3;
+ photometric = PHOTOMETRIC_RGB;
+ break;
+ case cmyk_2d: /* CMYK */
+ samplesperpixel = 4;
+ photometric = PHOTOMETRIC_SEPARATED;
+ inkset = INKSET_CMYK;
+ inknames = "cyan\000magenta\000yellow\000\000";
+ break;
+ case ncol_2d: /* N color */
+ samplesperpixel = s->ncc;
+ extrasamples = 0;
+ photometric = PHOTOMETRIC_SEPARATED;
+ inkset = 0; // ~~99 should fix this
+ inknames = NULL; // ~~99 should fix this
+ break;
+ case ncol_a_2d: /* N color with extras in alpha */
+ samplesperpixel = s->ncc;
+ extrasamples = 0;
+ if (samplesperpixel > 4) {
+ extrasamples = samplesperpixel - 4; /* Call samples > 4 "alpha" samples */
+ for (j = 0; j < extrasamples; j++)
+ extrainfo[j] = EXTRASAMPLE_UNASSALPHA;
+ }
+ photometric = PHOTOMETRIC_SEPARATED;
+ inkset = 0; // ~~99 should fix this
+ inknames = NULL; // ~~99 should fix this
+ break;
+ default:
+ error("render2d: Illegal colorspace for file '%s'",filename);
+ }
+ if (samplesperpixel != s->ncc)
+ error("render2d: mismatched number of color components");
+
+ switch (s->dpth) {
+ case bpc8_2d: /* 8 bits per component */
+ bitspersample = 8;
+ break;
+ case bpc16_2d: /* 16 bits per component */
+ bitspersample = 16;
+ break;
+ default:
+ error("render2d: Illegal bits per component for file '%s'",filename);
+ }
+
+ if ((wh = TIFFOpen(filename, "w")) == NULL)
+ error("render2d: Can\'t create TIFF file '%s'!",filename);
+
+ TIFFSetField(wh, TIFFTAG_IMAGEWIDTH, s->pw);
+ TIFFSetField(wh, TIFFTAG_IMAGELENGTH, s->ph);
+ TIFFSetField(wh, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
+ TIFFSetField(wh, TIFFTAG_SAMPLESPERPIXEL, samplesperpixel);
+ TIFFSetField(wh, TIFFTAG_BITSPERSAMPLE, bitspersample);
+ TIFFSetField(wh, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
+ TIFFSetField(wh, TIFFTAG_PHOTOMETRIC, photometric);
+ if (extrasamples > 0)
+ TIFFSetField(wh, TIFFTAG_EXTRASAMPLES, extrasamples, extrainfo);
+
+ if (inknames != NULL) {
+ int inlen = zzstrlen(inknames);
+ TIFFSetField(wh, TIFFTAG_INKSET, inkset);
+ TIFFSetField(wh, TIFFTAG_INKNAMES, inlen, inknames);
+ }
+ TIFFSetField(wh, TIFFTAG_COMPRESSION, COMPRESSION_NONE);
+ TIFFSetField(wh, TIFFTAG_RESOLUTIONUNIT, RESUNIT_CENTIMETER);
+ TIFFSetField(wh, TIFFTAG_XRESOLUTION, 10.0 * s->hres); /* Cvt. to pixels/cm */
+ TIFFSetField(wh, TIFFTAG_YRESOLUTION, 10.0 * s->vres);
+ TIFFSetField(wh, TIFFTAG_XPOSITION, 0.1 * s->lm); /* Cvt. to cm */
+ TIFFSetField(wh, TIFFTAG_YPOSITION, 0.1 * s->tm);
+ if (comprn) {
+ TIFFSetField(wh, TIFFTAG_COMPRESSION, COMPRESSION_LZW);
+ }
+ TIFFSetField(wh, TIFFTAG_IMAGEDESCRIPTION, "Test chart created with Argyll");
+
+ /* Allocate pixel value storage for aliasing detection */
+ if ((_pixv0 = malloc(sizeof(color2d) * (s->pw+2))) == NULL)
+ return 1;
+ pixv0 = _pixv0+1;
+ if ((_pixv1 = malloc(sizeof(color2d) * (s->pw+2))) == NULL)
+ return 1;
+ pixv1 = _pixv1+1;
+
+ /* Allocate one TIFF line buffer */
+ outbuf = _TIFFmalloc(TIFFScanlineSize(wh));
+
+ if (s->dpth == bpc8_2d && s->dither) {
+#ifdef NEVER // For testing by making screen visible
+# define LEVELS 16
+ int i, olevs[LEVELS];
+ for (i = 0; i < LEVELS; i++)
+ olevs[i] = (int)(i/(LEVELS-1.0) * 255.0 + 0.5);
+ if ((screen = new_thscreens(0, s->ncc, 1.0, 79, scie_16, 8, LEVELS, olevs,
+ scoo_l, 0.1, NULL, NULL)) == NULL)
+#else
+ if ((screen = new_thscreens(0, s->ncc, 1.0, 79, scie_16, 8, 256, NULL,
+ scoo_l, 0.1, NULL, NULL)) == NULL)
+#endif
+ return 1;
+ if ((tempbuf = malloc(s->pw * s->ncc * 2)) == NULL)
+ return 1;
+ }
+
+ /* To accelerate rendering, we keep sorted Y and X lists, */
+ /* and Y and X active linked lists derived from them. */
+ /* Typically this means that we're calling render on */
+ /* none, 1 or a handful of the primitives, greatly speeding up */
+ /* rendering. */
+
+ /* Allocate X and Y ordered lists */
+ if ((ylist = malloc(sizeof(prim2d *) * s->ix)) == NULL)
+ return 1;
+ if ((xlist = malloc(sizeof(prim2d *) * s->ix)) == NULL)
+ return 1;
+
+ /* Initialise the Y list */
+ for (th = s->head, i = 0; th != NULL; th = th->next, i++)
+ ylist[i] = th;
+
+ /* Sort the Y lists by y1 (because we rasterise top to bottom) */
+#define HEAP_COMPARE(A,B) (A->y1 > B->y1)
+ HEAPSORT(prim2d *,ylist,s->ix)
+#undef HEAP_COMPARE
+ yli = 0;
+ s->yl = NULL;
+
+ /* Render each line and write it. */
+ /* We sample +- half a pixel around the pixel we want. */
+ /* We make the active element list encompass this region, */
+ /* so that we can super sample it for anti-aliasing. */
+ for (y = -1; y < s->ph; y++) {
+
+ ry0 = (((s->ph-1) - y) - 0.5) / s->vres;
+ ry1 = (((s->ph-1) - y) + 0.5) / s->vres;
+
+ /* Remove any objects from the y list that are now out of range */
+ for (pthp = &s->yl, th = s->yl; th != NULL;) {
+ if (ry1 < th->y0) {
+ *pthp = th->yl;
+ th = th->yl;
+ } else {
+ pthp = &th->yl;
+ th = th->yl;
+ }
+ }
+
+ /* Add any objects that are now within this range to our y list */
+ for(; yli < s->ix && ry0 < ylist[yli]->y1; yli++) {
+ ylist[yli]->yl = s->yl;
+ s->yl = ylist[yli];
+ }
+
+ /* Initialise the current X list */
+ for (th = s->yl, noix = 0; th != NULL; th = th->yl, noix++)
+ xlist[noix] = th;
+
+ /* Sort the X lists by x0 */
+#define HEAP_COMPARE(A,B) (A->x0 < B->x0)
+ HEAPSORT(prim2d *,xlist,noix)
+#undef HEAP_COMPARE
+ xli = 0;
+ s->xl = NULL;
+
+ for (x = -1; x < s->pw; x++) {
+ int j;
+ color2d rv;
+
+ rx0 = (x - 0.5) / s->hres;
+ rx1 = (x + 0.5) / s->hres;
+
+ /* Add any objects that are now within this range to our x list */
+ for(; xli < noix && rx1 > xlist[xli]->x0; xli++) {
+ xlist[xli]->xl = s->xl;
+ s->xl = xlist[xli];
+ }
+
+ /* Set the default current color */
+ for (j = 0; j < s->ncc; j++)
+ pixv1[x][j] = s->defc[j];
+ pixv1[x][PRIX2D] = -1; /* Make sure all primitive ovewrite the default */
+
+ /* Allow callback to set per pixel background color (or not) */
+ if (s->bgfunc != NULL)
+ s->bgfunc(s->cntx, pixv1[x], x, y);
+
+ /* Overwrite it with any primitives, */
+ /* and remove any that are out of range now */
+ for (pthp = &s->xl, th = s->xl; th != NULL;) {
+ if (rx0 > th->x1) {
+ *pthp = th->xl;
+ th = th->xl;
+ } else {
+ if (th->rend(th, rv, rx1, ry0) && th->ix > pixv1[x][PRIX2D]) {
+ /* Overwrite the current color */
+ /* (This is where we should handle depth and opacity */
+ for (j = 0; j < s->ncc; j++)
+ pixv1[x][j] = rv[j];
+ pixv1[x][PRIX2D] = rv[PRIX2D];
+ }
+ pthp = &th->xl;
+ th = th->xl;
+ }
+ }
+ /* Check if anti-aliasing is neded for previous lines previous pixel */
+ if (y >= 0 && x >= 0) {
+ color2d cc;
+
+ for (j = 0; j < s->ncc; j++)
+ cc[j] = pixv1[x][j];
+ cc[PRIX2D] = pixv1[x][PRIX2D];
+
+ /* See if anti aliasing is needed */
+ if ((pixv0[x+0][PRIX2D] != cc[PRIX2D] && colordiff(s, pixv0[x+0], cc))
+ || (pixv0[x-1][PRIX2D] != cc[PRIX2D] && colordiff(s, pixv0[x-1], cc))
+ || (pixv1[x-1][PRIX2D] != cc[PRIX2D] && colordiff(s, pixv1[x-1], cc))) {
+ double nn = 0;
+
+ so->reset(so);
+
+ for (j = 0; j < s->ncc; j++)
+ cc[j] = 0.0;
+
+ /* Compute the sample value by re-sampling the region */
+ /* around the pixel. */
+ for (nn = 0; nn < OSAMLS; nn++) {
+ double pos[2];
+ double rx, ry;
+ color2d ccc;
+
+ so->next(so, pos);
+
+ rx = (rx1 - rx0) * pos[0] + rx0;
+ ry = (ry1 - ry0) * pos[1] + ry0;
+
+ /* Set the default current color */
+ for (j = 0; j < s->ncc; j++)
+ ccc[j] = s->defc[j];
+ ccc[PRIX2D] = -1;
+
+ for (th = s->xl; th != NULL; th = th->xl) {
+ if (th->rend(th, rv, rx, ry) && th->ix > ccc[PRIX2D]) {
+ /* Overwrite the current color */
+ /* (This is where we should handle depth and opacity */
+ for (j = 0; j < s->ncc; j++)
+ ccc[j] = rv[j];
+ ccc[PRIX2D] = rv[PRIX2D];
+ }
+ }
+ for (j = 0; j < s->ncc; j++)
+ cc[j] += pow(ccc[j], MIXPOW);
+ }
+ for (j = 0; j < s->ncc; j++)
+ cc[j] = pow(cc[j]/nn, 1.0/MIXPOW);
+
+#ifdef NEVER /* Mark aliased pixels */
+ cc[0] = 0.5;
+ cc[1] = 0.0;
+ cc[2] = 1.0;
+#endif
+ } else {
+
+ /* Compute output value as mean of surrounding samples */
+ for (j = 0; j < s->ncc; j++) {
+ cc[j] = cc[j]
+ + pixv0[x-1][j]
+ + pixv0[x][j]
+ + pixv1[x-1][j];
+ cc[j] = cc[j] * 0.25;
+
+ }
+ }
+
+ /* Translate from render value to output pixel value */
+ if (s->dpth == bpc8_2d) {
+ if (s->dither) {
+ unsigned short *p = ((unsigned short *)tempbuf) + x * s->ncc;
+ if (s->csp == lab_2d) {
+ cvt_Lab_to_CIELAB16(cc, cc);
+ for (j = 0; j < s->ncc; j++)
+ p[j] = (int)(cc[j] + 0.5);
+ } else {
+ for (j = 0; j < s->ncc; j++)
+ p[j] = (int)(65535.0 * cc[j] + 0.5);
+ }
+ } else {
+ unsigned char *p = ((unsigned char *)outbuf) + x * s->ncc;
+ if (s->csp == lab_2d) {
+ cvt_Lab_to_CIELAB8(cc, cc);
+ for (j = 0; j < s->ncc; j++)
+ p[j] = (int)(cc[j] + 0.5);
+ } else {
+ for (j = 0; j < s->ncc; j++)
+ p[j] = (int)(255.0 * cc[j] + 0.5);
+ }
+ }
+ } else {
+ unsigned short *p = ((unsigned short *)outbuf) + x * s->ncc;
+ if (s->csp == lab_2d) {
+ cvt_Lab_to_CIELAB16(cc, cc);
+ for (j = 0; j < s->ncc; j++)
+ p[j] = (int)(cc[j] + 0.5);
+ } else {
+ for (j = 0; j < s->ncc; j++)
+ p[j] = (int)(65535.0 * cc[j] + 0.5);
+ }
+ }
+ }
+ }
+
+ if (y >= 0) {
+ if (s->dpth == bpc8_2d && s->dither)
+ screen->screen(screen, s->pw, 1, 0, y, tempbuf, s->pw * s->ncc * 2,
+ (unsigned char *)outbuf, s->pw * s->ncc);
+
+ if (TIFFWriteScanline(wh, outbuf, y, 0) < 0)
+ error ("Failed to write TIFF file '%s' line %d",filename,y);
+ }
+
+ /* Shuffle the pointers */
+ {
+ color2d *ttt;
+ ttt = pixv0;
+ pixv0 = pixv1;
+ pixv1 = ttt;
+ }
+ }
+
+ free(ylist);
+ free(xlist);
+ free(_pixv0);
+ free(_pixv1);
+
+ if (tempbuf != NULL)
+ free(tempbuf);
+ if (screen != NULL)
+ screen->del(screen);
+ _TIFFfree(outbuf);
+ TIFFClose(wh); /* Close Output file */
+
+ so->del(so);
+
+ return 0;
+}
+
+/* Constructor */
+render2d *new_render2d(
+double w, /* width in mm */
+double h, /* height in mm */
+double ma[4], /* Margines, left, right, top, bottom, NULL for zero in mm */
+double hres, /* horizontal resolution in pixels/mm */
+double vres, /* horizontal resolution in pixels/mm */
+colort2d csp, /* Color type */
+int nd, /* Number of channels if c = ncol */
+depth2d dpth, /* Pixel depth */
+int dither /* Dither flag */
+) {
+ render2d *s;
+
+ if ((s = (render2d *)calloc(1, sizeof(render2d))) == NULL) {
+ return NULL;
+ }
+
+ s->fw = w;
+ s->fh = h;
+ if (ma != NULL) {
+ s->lm = ma[0];
+ s->rm = ma[1];
+ s->tm = ma[2];
+ s->bm = ma[3];
+ }
+ w = s->fw - s->lm - s->rm;
+ h = s->fh - s->tm - s->bm;
+ if (w < 0.0)
+ error("render2d: Left & Right margines %f %f exceed width %f",s->lm,s->rm,s->fw);
+ if (h < 0.0)
+ error("render2d: Top & Bottom margines %f %f exceed height %f",s->tm,s->bm,s->fh);
+ s->hres = hres;
+ s->vres = vres;
+ s->csp = csp;
+ s->dpth = dpth;
+ s->dither = dither;
+
+ s->del = render2d_del;
+ s->set_defc = render2d_set_defc;
+ s->set_bg_func = render2d_set_bg_func;
+ s->add = render2d_add;
+ s->write = render2d_write;
+
+ /* Figure the raster size and actuall size */
+ s->pw = (int)(s->hres * w + 0.5);
+ s->ph = (int)(s->vres * h + 0.5);
+ s->w = s->pw * s->hres;
+ s->h = s->ph * s->vres;
+
+ switch (s->csp) {
+ case w_2d: /* Video style grey */
+ case k_2d: /* Printing style grey */
+ s->ncc = 1;
+ break;
+ case lab_2d: /* TIFF CIE L*a*b* */
+ s->ncc = 3;
+ break;
+ case rgb_2d: /* RGB */
+ s->ncc = 3;
+ break;
+ case cmyk_2d: /* CMYK */
+ s->ncc = 4;
+ break;
+ case ncol_2d:
+ case ncol_a_2d:
+ if (nd > MXCH2D)
+ error("render2d: Too many color chanels %d, max is %d",nd,MXCH2D);
+ s->ncc = nd;
+ break;
+ default:
+ error("render2d: Illegal colorspace");
+ }
+ return s;
+}
+
+/* ------------------------------------------------------------- */
+/* Primitive implementations */
+
+/* Primitive destructor for no sub-allocation */
+static void prim2d_del(prim2d *s) {
+ free(s);
+}
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+/* Flat shaded rectangle */
+
+/* Render the rectangle object at location. Return nz if in primitive */
+static int rect2d_rend(prim2d *ss, color2d rv, double x, double y) {
+ rect2d *s = (rect2d *)ss;
+ int j;
+
+ if (y < s->ry0 || y > s->ry1
+ || x < s->rx0 || x > s->rx1)
+ return 0;
+
+ for (j = 0; j < s->ncc; j++)
+ rv[j] = s->c[j];
+ rv[PRIX2D] = s->ix;
+
+ return 1;
+}
+
+prim2d *new_rect2d(
+render2d *ss,
+double x,
+double y,
+double w,
+double h,
+color2d c
+) {
+ int j;
+ rect2d *s;
+
+ if ((s = (rect2d *)calloc(1, sizeof(rect2d))) == NULL) {
+ return NULL;
+ }
+
+ /* Account for margines */
+ x -= ss->lm;
+ y -= ss->bm;
+
+ s->ncc = ss->ncc;
+ s->del = prim2d_del;
+ s->rend = rect2d_rend;
+
+ /* Set bounding box */
+ s->x0 = x;
+ s->y0 = y;
+ s->x1 = x + w;
+ s->y1 = y + h;
+
+ /* Set rectangle extent */
+ s->rx0 = s->x0;
+ s->ry0 = s->y0;
+ s->rx1 = s->x1;
+ s->ry1 = s->y1;
+
+ for (j = 0; j < s->ncc; j++)
+ s->c[j] = c[j];
+
+ return (prim2d *)s;
+}
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+/* Vertex shaded rectangle */
+
+/* Render the rectangle object at location. Return nz if in primitive */
+static int rectvs2d_rend(prim2d *ss, color2d rv, double x, double y) {
+ rectvs2d *s = (rectvs2d *)ss;
+ double bx, by, b[4];
+ int i, j;
+
+ if (y < s->ry0 || y > s->ry1
+ || x < s->rx0 || x > s->rx1)
+ return 0;
+
+ /* Compute linear blend */
+ bx = (x - s->x0)/(s->x1 - s->x0);
+ by = (y - s->y0)/(s->y1 - s->y0);
+
+ if (s->x_blend == 1) {
+ bx = bx * bx * (3.0 - 2.0 * bx); /* Cubic spline */
+ } else if (s->x_blend == 2) {
+ bx = bx - 0.5; /* Sine */
+ bx *= 3.141592654;
+ bx = sin(bx);
+ bx = 0.5 + (0.5 * bx);
+ }
+ if (s->y_blend == 1) {
+ by = by * by * (3.0 - 2.0 * by); /* Spline */
+ } else if (s->y_blend == 2) {
+ double ty;
+ ty = by * by * (3.0 - 2.0 * by); /* spline at y == 1, linear at y == 0 */
+ by = by * ty + (1.0 - by) * by;
+ } else if (s->y_blend == 3) {
+ double ty;
+ ty = by * by * (3.0 - 2.0 * by); /* linear at y == 1, spline at y == 0 */
+ by = (1.0 - by) * ty + by * by;
+ }
+
+ /* Compute 2d blend */
+ b[0] = (1.0 - by) * (1.0 - bx);
+ b[1] = (1.0 - by) * bx;
+ b[2] = by * (1.0 - bx);
+ b[3] = by * bx;
+
+ /* Compute the resulting color */
+ for (j = 0; j < s->ncc; j++) {
+ rv[j] = 0.0;
+ for (i = 0; i < 4; i++)
+ rv[j] += b[i] * s->c[i][j];
+ rv[j] = rv[j];
+ }
+ rv[PRIX2D] = s->ix;
+
+ return 1;
+}
+
+prim2d *new_rectvs2d(
+render2d *ss,
+double x,
+double y,
+double w,
+double h,
+color2d c[4]
+) {
+ int i, j;
+ rectvs2d *s;
+
+ if ((s = (rectvs2d *)calloc(1, sizeof(rectvs2d))) == NULL) {
+ return NULL;
+ }
+
+ /* Account for margines */
+ x -= ss->lm;
+ y -= ss->bm;
+
+ s->ncc = ss->ncc;
+ s->del = prim2d_del;
+ s->rend = rectvs2d_rend;
+
+ /* Set bounding box */
+ s->x0 = x;
+ s->y0 = y;
+ s->x1 = x + w;
+ s->y1 = y + h;
+
+ /* Set rectangle extent */
+ s->rx0 = s->x0;
+ s->ry0 = s->y0;
+ s->rx1 = s->x1;
+ s->ry1 = s->y1;
+
+ for (i = 0; i < 4; i++)
+ for (j = 0; j < s->ncc; j++)
+ s->c[i][j] = c[i][j];
+
+ return (prim2d *)s;
+}
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+/* Vertex shaded triangle */
+
+/* Render the triangle object at location. Return nz if in primitive */
+static int trivs2d_rend(prim2d *ss, color2d rv, double x, double y) {
+ trivs2d *s = (trivs2d *)ss;
+ double b[3];
+ int i, j;
+
+ /* Compute the baricentric values for the input point, */
+ /* and reject this point if it is outside the triangle */
+ for (i = 0; i < 3; i++) {
+ b[i] = s->be[i][0] * x + s->be[i][1] * y + s->be[i][2];
+ if (b[i] < 0.0 || b[i] > 1.0)
+ return 0;
+ }
+
+#ifdef NEVER /* Experiment with smoothing hue blending */
+ {
+ double ss = b[1] + b[2];
+ if (ss > 1e-6) {
+ b[1] /= ss;
+ b[2] /= ss;
+// b[1] = b[1] * b[1] * (3.0 - 2.0 * b[1]);
+
+ b[1] = b[1] - 0.5;
+ b[1] *= 3.141592654;
+ b[1] = sin(b[1]);
+ b[1] = 0.5 + (0.5 * b[1]);
+
+ b[2] = 1.0 - b[1];
+ b[1] *= ss;
+ b[2] *= ss;
+ }
+ }
+#endif
+
+ /* Compute the resulting color */
+ for (j = 0; j < s->ncc; j++) {
+ rv[j] = 0.0;
+ for (i = 0; i < 3; i++)
+ rv[j] += b[i] * s->c[i][j];
+ }
+ rv[PRIX2D] = s->ix;
+
+ return 1;
+}
+
+static int inverse3x3(double out[3][3], double in[3][3]);
+
+prim2d *new_trivs2d(
+render2d *ss,
+double v[3][2], /* Vertex locations */
+color2d c[3] /* Corresponding colors */
+) {
+ int i, j;
+ trivs2d *s;
+ double vv[3][2]; /* Margin adjusted vertex locations */
+ double tt[3][3];
+
+ if ((s = (trivs2d *)calloc(1, sizeof(trivs2d))) == NULL) {
+ return NULL;
+ }
+
+ /* Account for margines */
+ for (i = 0; i < 3; i++) {
+ vv[i][0] = v[i][0] - ss->lm;
+ vv[i][1] = v[i][1] - ss->bm;
+ }
+
+ s->ncc = ss->ncc;
+ s->del = prim2d_del;
+ s->rend = trivs2d_rend;
+
+ /* Set the bounding box values */
+ s->x0 = s->y0 = 1e38;
+ s->x1 = s->y1 = -1e38;
+ for (i = 0; i < 3; i++) {
+ if (vv[i][0] < s->x0)
+ s->x0 = vv[i][0];
+ if (vv[i][1] < s->y0)
+ s->y0 = vv[i][1];
+ if (vv[i][0] > s->x1)
+ s->x1 = vv[i][0];
+ if (vv[i][1] > s->y1)
+ s->y1 = vv[i][1];
+ }
+
+ /* Compute baricentric equations */
+ for (i = 0; i < 3; i++) {
+ tt[0][i] = vv[i][0];
+ tt[1][i] = vv[i][1];
+ tt[2][i] = 1.0;
+ }
+ if (inverse3x3(s->be, tt))
+ error("trivs2d: Matrix inversion failed");
+
+ /* Copy vertex colors */
+ for (i = 0; i < 3; i++) {
+ for (j = 0; j < s->ncc; j++)
+ s->c[i][j] = c[i][j];
+ }
+
+ return (prim2d *)s;
+}
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+/* A single Rounded end line. Mainly for supporting Hershey text output. */
+
+/* Render the line object at this location */
+static int line2d_rend(prim2d *ss, color2d rv, double x, double y) {
+ line2d *s = (line2d *)ss;
+ double rr, px, py;
+ int j;
+
+ px = x - s->lx0; /* Input relative to x0 y0 */
+ py = y - s->ly0;
+
+ /* It's actually a point */
+ if (s->t) {
+
+ rr = (px * px) + (py * py) ;
+
+ if (s->cap != 1)
+ return 0;
+ if (rr > s->ww)
+ return 0;
+
+ } else {
+ /* Locate point on line between 0 and 1 closest to input point */
+ double t, nx, ny;
+
+ /* Closest point on line parametric value */
+ t = (s->vx * px + s->vy * py)/(s->vx * s->vx + s->vy * s->vy);
+
+ if (t < 0.0) { /* 0 side end cap */
+ if (s->cap != 1)
+ return 0;
+ rr = (px * px) + (py * py) ;
+ if (rr > s->ww)
+ return 0; /* 1 side end cap */
+
+ } else if (t > 1.0) {
+ if (s->cap != 1)
+ return 0;
+ rr = (x - s->lx1) * (x - s->lx1)
+ + (y - s->ly1) * (y - s->ly1);
+ if (rr > s->ww)
+ return 0;
+
+ } else { /* Within rectangular part of line */
+ double nx, ny;
+
+ nx = t * s->vx; /* Closest point on line relative to x0 y0 */
+ ny = t * s->vy;
+
+ rr = (px - nx) * (px - nx) + (py - ny) * (py - ny);
+ if (rr > s->ww)
+ return 0;
+ }
+ }
+
+ for (j = 0; j < s->ncc; j++)
+ rv[j] = s->c[j];
+ rv[PRIX2D] = s->ix;
+
+ return 1;
+}
+
+prim2d *new_line2d(
+render2d *ss,
+double x0, double y0, double x1, double y1,
+double w,
+int cap, /* 0 = butt, 1 = round, 2 = square */
+color2d c
+) {
+ int i, j;
+ line2d *s;
+ double tt[3][3];
+
+ if ((s = (line2d *)calloc(1, sizeof(line2d))) == NULL) {
+ return NULL;
+ }
+
+ /* Account for margines */
+ x0 -= ss->lm;
+ y0 -= ss->bm;
+ x1 -= ss->lm;
+ y1 -= ss->bm;
+
+ s->ncc = ss->ncc;
+ s->del = prim2d_del;
+ s->rend = line2d_rend;
+
+ w *= 0.5; /* half width */
+
+ for (j = 0; j < s->ncc; j++)
+ s->c[j] = c[j];
+
+ /* Compute the line vector relative to x0 y0 */
+ s->vx = x1 - x0;
+ s->vy = y1 - y0;
+
+ /* For square, extend the line by w/2 and render as butt */
+ if (cap == 2) {
+ double nvx, nvy;
+ double ll = sqrt(s->vx * s->vx + s->vy * s->vy);
+
+ /* Compute normalized vector */
+ if (ll < 1e-6) {
+ nvx = 1.0;
+ nvy = 0.0;
+ } else {
+ nvx = s->vx/ll;
+ nvy = s->vy/ll;
+ }
+ x0 -= w * nvx;
+ y0 -= w * nvy;
+ x1 += w * nvx;
+ y1 += w * nvy;
+ s->vx = x1 - x0;
+ s->vy = y1 - y0;
+ }
+
+ s->lx0 = x0;
+ s->ly0 = y0;
+ s->lx1 = x1;
+ s->ly1 = y1;
+ s->ww = w * w;
+ s->cap = cap;
+
+ /* Set the bouding box values */
+ if (x1 > x0) {
+ s->x1 = x1 + w;
+ s->x0 = x0 - w;
+ } else {
+ s->x1 = x0 + w;
+ s->x0 = x1 - w;
+ }
+ if (y1 > y0) {
+ s->y1 = y1 + w;
+ s->y0 = y0 - w;
+ } else {
+ s->y1 = y0 + w;
+ s->y0 = y1 - w;
+ }
+
+ /* Figure out if the line is degenerate */
+ if (fabs(s->vx) < 1e-6 && fabs(s->vy) < 1e-6) {
+ s->t = 1;
+ }
+
+ return (prim2d *)s;
+}
+
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+/* Primitive Macros. */
+
+/* add a dashed line */
+void add_dashed_line2d(
+struct _render2d *s,
+double x0, double y0,
+double x1, double y1,
+double w,
+double on, double off,
+int cap,
+color2d c) {
+ double ll, rl; /* Line length, rounded length */
+ double vx, vy;
+ double nvx, nvy; /* Normalized vector */
+
+ vx = x1 - x0;
+ vy = y1 - y0;
+ ll = sqrt(vx * vx + vy * vy);
+
+ if (ll < 1e-6) {
+ s->add(s, new_line2d(s, x0, y0, x1, y1, w, cap, c));
+ return ;
+ }
+ nvx = vx/ll;
+ nvy = vy/ll;
+
+ for (;ll > 0.0;) {
+ rl = ll;
+ if (rl > on) {
+ rl = on;
+ }
+ x1 = x0 + rl * nvx;
+ y1 = y0 + rl * nvy;
+ s->add(s, new_line2d(s, x0, y0, x1, y1, w, cap, c));
+ x0 = x1;
+ y0 = y1;
+ ll -= rl;
+ if (ll <= 0.0)
+ return;
+ rl = ll;
+ if (rl > off) {
+ rl = off;
+ }
+ x0 += rl * nvx;
+ y0 += rl * nvy;
+ ll -= rl;
+ }
+}
+
+
+/* Text */
+struct _hyfont {
+ char *name;
+ double sx, sy; /* X and Y scaling */
+ double sxi; /* X spacing extra scale */
+ double sw; /* Line width scale */
+ double ho; /* horizontal alignment offset */
+ double vo; /* vertical alignment offset */
+ char *enc[128]; /* Hershey encoded font */
+}; typedef struct _hyfont hyfont;
+
+hyfont fonts[];
+
+double h2dbl(unsigned char c) { return (double)(c-'R'); }
+
+/* Add a text character at the given location using lines */
+static void add_char_imp(
+render2d *s,
+double *xinc, /* Add increment to next character */
+double *yinc,
+font2d fo, /* Font to use */
+char ch, /* Character code to be printed */
+double x, double y, /* Location of bottom left of normal orientation text */
+double h, /* Height of text in normal orientation */
+int or, /* Orintation, 0 = right, 1 = down, 2 = left, 3 = right */
+color2d c, /* Color of text */
+int add /* NZ if character is to be added */
+) {
+ hyfont *fp = &fonts[fo];
+ char *cp = fp->enc[ch % 128];
+ double lm, rm;
+ double x0, y0, x1 = 0.0, y1 = 0.0;
+ int got1 = 0;
+ double w = fp->sw * h;
+ double tx, ty;
+ double mat[2][2]; /* Transformation matrix */
+
+ if (or == 0) {
+ mat[0][0] = 1.0;
+ mat[0][1] = 0.0;
+ mat[1][0] = 0.0;
+ mat[1][1] = 1.0;
+ } else if (or == 1) {
+ mat[0][0] = 0.0;
+ mat[0][1] = 1.0;
+ mat[1][0] = -1.0;
+ mat[1][1] = 0.0;
+ } else if (or == 2) {
+ mat[0][0] = -1.0;
+ mat[0][1] = 0.0;
+ mat[1][0] = 0.0;
+ mat[1][1] = -1.0;
+ } else {
+ mat[0][0] = 0.0;
+ mat[0][1] = -1.0;
+ mat[1][0] = 1.0;
+ mat[1][1] = 0.0;
+ }
+ if (cp[0] == '\000' || cp[1] == '\000') {
+ if (xinc != NULL && yinc != NULL) {
+ *xinc = 0.0;
+ *yinc = 0.0;
+ }
+ return;
+ }
+
+ lm = h2dbl(cp[0]);
+ rm = h2dbl(cp[1]);
+ cp += 2;
+
+ if (add) {
+ for (;; cp += 2) {
+ if (cp[0] == '\000' || cp[1] == '\000') {
+ break;
+ }
+ /* End of polyline */
+ if (cp[0] == ' ' && cp[1] == 'R' ) {
+ got1 = 0;
+ } else {
+ x0 = x1;
+ y0 = y1;
+ tx = h * fp->sx * (h2dbl(cp[0]) -lm + fp->ho);
+ ty = -h * fp->sy * (h2dbl(cp[1]) -fp->vo);
+ x1 = x + mat[0][0] * tx + mat[0][1] * ty;
+ y1 = y + mat[1][0] * tx + mat[1][1] * ty;
+ if (got1) {
+ s->add(s, new_line2d(s, x0, y0, x1, y1, w, 1, c));
+ }
+ got1 = 1;
+ }
+ }
+ }
+
+ tx = fp->sxi * h * fp->sx * (rm - lm);
+ ty = 0.0;
+ if (xinc != NULL)
+ *xinc += mat[0][0] * tx + mat[0][1] * ty;
+ if (yinc != NULL)
+ *yinc += mat[1][0] * tx + mat[1][1] * ty;
+}
+
+/* Add a text character at the given location using lines */
+void add_char2d(
+render2d *s,
+double *xinc, /* Add increment to next character */
+double *yinc,
+font2d fo, /* Font to use */
+char ch, /* Character code to be printed */
+double x, double y, /* Location of bottom left of normal orientation text */
+double h, /* Height of text in normal orientation */
+int or, /* Orintation, 0 = right, 1 = down, 2 = left, 3 = right */
+color2d c /* Color of text */
+) {
+ add_char_imp(s, xinc, yinc, fo, ch, x, y, h, or, c, 1);
+}
+
+/* Return the total width of the character without adding it */
+void meas_char2d(
+render2d *s,
+double *xinc, /* Add increment to next character */
+double *yinc,
+font2d fo, /* Font to use */
+char ch, /* Character code to be printed */
+double h, /* Height of text in normal orientation */
+int or /* Orintation, 0 = right, 1 = down, 2 = left, 3 = right */
+) {
+ color2d c;
+
+ add_char_imp(s, xinc, yinc, fo, ch, 0.0, 0.0, h, or, c, 0);
+}
+
+/* Add a string from the given location using lines. */
+/* Return the total width of the string */
+void add_string2d(
+render2d *s,
+double *xinc, /* Add increment to next character */
+double *yinc,
+font2d fo, /* Font to use */
+char *string, /* Character code to be printed */
+double x, double y, /* Location of bottom left of normal orientation text */
+double h, /* Height of text in normal orientation */
+int or, /* Orintation, 0 = right, 1 = down, 2 = left, 3 = right */
+color2d c /* Color of text */
+) {
+ char *ch;
+ double xoff = 0.0, yoff = 0.0;
+
+ for (ch = string; *ch != '\000'; ch++) {
+ add_char2d(s, &xoff, &yoff, fo, *ch, x + xoff, y + yoff, h, or, c);
+ }
+
+ if (xinc != NULL)
+ *xinc = xoff;
+ if (yinc != NULL)
+ *yinc = yoff;
+}
+
+/* Return the total width of the string without adding it */
+void meas_string2d(
+struct _render2d *s,
+double *xinc, /* Add increment to next character */
+double *yinc,
+font2d fo, /* Font to use */
+char *string, /* Character code to be printed */
+double h, /* Height of text in normal orientation */
+int or /* Orintation, 0 = right, 1 = down, 2 = left, 3 = right */
+) {
+ char *ch;
+ double xoff = 0.0, yoff = 0.0;
+
+ for (ch = string; *ch != '\000'; ch++) {
+ meas_char2d(s, &xoff, &yoff, fo, *ch, h, or);
+ }
+
+ if (xinc != NULL)
+ *xinc = xoff;
+ if (yinc != NULL)
+ *yinc = yoff;
+}
+
+/* ==================================================== */
+/* Misc. support functions. */
+
+/*
+ Matrix Inversion
+ by Richard Carling
+ from "Graphics Gems", Academic Press, 1990
+*/
+
+/*
+ * adjoint( original_matrix, inverse_matrix )
+ *
+ * calculate the adjoint of a 3x3 matrix
+ *
+ * Let a denote the minor determinant of matrix A obtained by
+ * ij
+ *
+ * deleting the ith row and jth column from A.
+ *
+ * i+j
+ * Let b = (-1) a
+ * ij ji
+ *
+ * The matrix B = (b ) is the adjoint of A
+ * ij
+ */
+
+#define det2x2(a, b, c, d) (a * d - b * c)
+
+static void adjoint(
+double out[3][3],
+double in[3][3]
+) {
+ double a1, a2, a3, b1, b2, b3, c1, c2, c3;
+
+ /* assign to individual variable names to aid */
+ /* selecting correct values */
+
+ a1 = in[0][0]; b1 = in[0][1]; c1 = in[0][2];
+ a2 = in[1][0]; b2 = in[1][1]; c2 = in[1][2];
+ a3 = in[2][0]; b3 = in[2][1]; c3 = in[2][2];
+
+ /* row column labeling reversed since we transpose rows & columns */
+
+ out[0][0] = det2x2(b2, b3, c2, c3);
+ out[1][0] = - det2x2(a2, a3, c2, c3);
+ out[2][0] = det2x2(a2, a3, b2, b3);
+
+ out[0][1] = - det2x2(b1, b3, c1, c3);
+ out[1][1] = det2x2(a1, a3, c1, c3);
+ out[2][1] = - det2x2(a1, a3, b1, b3);
+
+ out[0][2] = det2x2(b1, b2, c1, c2);
+ out[1][2] = - det2x2(a1, a2, c1, c2);
+ out[2][2] = det2x2(a1, a2, b1, b2);
+}
+
+/*
+ * double = det3x3( a1, a2, a3, b1, b2, b3, c1, c2, c3 )
+ *
+ * calculate the determinant of a 3x3 matrix
+ * in the form
+ *
+ * | a1, b1, c1 |
+ * | a2, b2, c2 |
+ * | a3, b3, c3 |
+ */
+
+static double det3x3(double in[3][3]) {
+ double a1, a2, a3, b1, b2, b3, c1, c2, c3;
+ double ans;
+
+ a1 = in[0][0]; b1 = in[0][1]; c1 = in[0][2];
+ a2 = in[1][0]; b2 = in[1][1]; c2 = in[1][2];
+ a3 = in[2][0]; b3 = in[2][1]; c3 = in[2][2];
+
+ ans = a1 * det2x2(b2, b3, c2, c3)
+ - b1 * det2x2(a2, a3, c2, c3)
+ + c1 * det2x2(a2, a3, b2, b3);
+ return ans;
+}
+
+#define SMALL_NUMBER 1.e-8
+/*
+ * inverse( original_matrix, inverse_matrix )
+ *
+ * calculate the inverse of a 4x4 matrix
+ *
+ * -1
+ * A = ___1__ adjoint A
+ * det A
+ */
+
+/* Return non-zero if not invertable */
+static int inverse3x3(
+double out[3][3],
+double in[3][3]
+) {
+ int i, j;
+ double det;
+
+ /* calculate the 3x3 determinant
+ * if the determinant is zero,
+ * then the inverse matrix is not unique.
+ */
+ det = det3x3(in);
+
+ if ( fabs(det) < SMALL_NUMBER)
+ return 1;
+
+ /* calculate the adjoint matrix */
+ adjoint(out, in);
+
+ /* scale the adjoint matrix to get the inverse */
+ for (i = 0; i < 3; i++)
+ for(j = 0; j < 3; j++)
+ out[i][j] /= det;
+ return 0;
+}
+
+/* ==================================================== */
+// Hershey.C
+// extracted from the hershey font
+//
+// Charles Schwieters 6/14/99
+// Various tweaks and updates by John Stone
+//
+// font info:
+//
+//Peter Holzmann, Octopus Enterprises
+//USPS: 19611 La Mar Court, Cupertino, CA 95014
+//UUCP: {hplabs!hpdsd,pyramid}!octopus!pete
+//Phone: 408/996-7746
+//
+//This distribution is made possible through the collective encouragement
+//of the Usenet Font Consortium, a mailing list that sprang to life to get
+//this accomplished and that will now most likely disappear into the mists
+//of time... Thanks are especially due to Jim Hurt, who provided the packed
+//font data for the distribution, along with a lot of other help.
+//
+//This file describes the Hershey Fonts in general, along with a description of
+//the other files in this distribution and a simple re-distribution restriction.
+//
+//USE RESTRICTION:
+// This distribution of the Hershey Fonts may be used by anyone for
+// any purpose, commercial or otherwise, providing that:
+// 1. The following acknowledgements must be distributed with
+// the font data:
+// - The Hershey Fonts were originally created by Dr.
+// A. V. Hershey while working at the U. S.
+// National Bureau of Standards.
+// - The format of the Font data in this distribution
+// was originally created by
+// James Hurt
+// Cognition, Inc.
+// 900 Technology Park Drive
+// Billerica, MA 01821
+// (mit-eddie!ci-dandelion!hurt)
+// 2. The font data in this distribution may be converted into
+// any other format *EXCEPT* the format distributed by
+// the U.S. NTIS (which organization holds the rights
+// to the distribution and use of the font data in that
+// particular format). Not that anybody would really
+// *want* to use their format... each point is described
+// in eight bytes as "xxx yyy:", where xxx and yyy are
+// the coordinate values as ASCII numbers.
+//
+
+/*
+ * The Hershey romans font in ascii order (first 32 places held by space)
+ * NOTE: This font has been modified to yield fixed-width numeric
+ * characters. This makes it possible to produce justified numeric
+ * text that correctly lines up in columns.
+ * The font was specifically changed for:
+ * ' ' (ascii 32), '+' (ascii 43), '-' (ascii 45), and '.' (ascii 46)
+ */
+
+hyfont fonts[] = {
+{
+ "Rowman Single",
+ 0.040, /* X scale */
+ 0.040, /* Y scale */
+ 0.95, /* X spacing extra scale */
+ 0.08, /* Line width scale */
+ 1.1, /* horizontal offset */
+ 11.0, /* vertical offset */
+ {
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "MWRFRT RRYQZR[SZRY",
+ "JZNFNM RVFVM",
+ "H]SBLb RYBRb RLOZO RKUYU",
+ "H\\PBP_ RTBT_ RYIWGTFPFMGKIKKLMMNOOUQWRXSYUYXWZT[P[MZKX",
+ "F^[FI[ RNFPHPJOLMMKMIKIIJGLFNFPGSHVHYG[F RWTUUTWTYV[X[ZZ[X[VYTWT",
+ "E_\\O\\N[MZMYNXPVUTXRZP[L[JZIYHWHUISJRQNRMSKSIRGPFNGMIMKNNPQUXWZY[",
+ "MWRHQGRFSGSIRKQL",
+ "KYVBTDRGPKOPOTPYR]T`Vb",
+ "KYNBPDRGTKUPUTTYR]P`Nb",
+ "JZRLRX RMOWU RWOMU",
+ "E_RIR[ RIR[R",
+ "NVSWRXQWRVSWSYQ[",
+ "E_IR[R",
+ "NVRVQWRXSWRV",
+ "G][BIb",
+ "H\\QFNGLJKOKRLWNZQ[S[VZXWYRYOXJVGSFQF",
+ "H\\NJPISFS[",
+ "H\\LKLJMHNGPFTFVGWHXJXLWNUQK[Y[",
+ "H\\MFXFRNUNWOXPYSYUXXVZS[P[MZLYKW",
+ "H\\UFKTZT RUFU[",
+ "H\\WFMFLOMNPMSMVNXPYSYUXXVZS[P[MZLYKW",
+ "H\\XIWGTFRFOGMJLOLTMXOZR[S[VZXXYUYTXQVOSNRNOOMQLT",
+ "H\\YFO[ RKFYF",
+ "H\\PFMGLILKMMONSOVPXRYTYWXYWZT[P[MZLYKWKTLRNPQOUNWMXKXIWGTFPF",
+ "H\\XMWPURRSQSNRLPKMKLLINGQFRFUGWIXMXRWWUZR[P[MZLX",
+ "NVROQPRQSPRO RRVQWRXSWRV",
+ "NVROQPRQSPRO RSWRXQWRVSWSYQ[",
+ "F^ZIJRZ[",
+ "E_IO[O RIU[U",
+ "F^JIZRJ[",
+ "I[LKLJMHNGPFTFVGWHXJXLWNVORQRT RRYQZR[SZRY",
+ "E`WNVLTKQKOLNMMPMSNUPVSVUUVS RQKOMNPNSOUPV RWKVSVUXVZV\\T]Q]O\\L[J",
+ "I[RFJ[ RRFZ[ RMTWT",
+ "G\\KFK[ RKFTFWGXHYJYLXNWOTP RKPTPWQXRYTYWXYWZT[K[",
+ "H]ZKYIWGUFQFOGMILKKNKSLVMXOZQ[U[WZYXZV",
+ "G\\KFK[ RKFRFUGWIXKYNYSXVWXUZR[K[",
+ "H[LFL[ RLFYF RLPTP RL[Y[",
+ "HZLFL[ RLFYF RLPTP",
+ "H]ZKYIWGUFQFOGMILKKNKSLVMXOZQ[U[WZYXZVZS RUSZS",
+ "G]KFK[ RYFY[ RKPYP",
+ "NVRFR[",
+ "JZVFVVUYTZR[P[NZMYLVLT",
+ "G\\KFK[ RYFKT RPOY[",
+ "HYLFL[ RL[X[",
+ "F^JFJ[ RJFR[ RZFR[ RZFZ[",
+ "G]KFK[ RKFY[ RYFY[",
+ "G]PFNGLIKKJNJSKVLXNZP[T[VZXXYVZSZNYKXIVGTFPF",
+ "G\\KFK[ RKFTFWGXHYJYMXOWPTQKQ",
+ "G]PFNGLIKKJNJSKVLXNZP[T[VZXXYVZSZNYKXIVGTFPF RSWY]",
+ "G\\KFK[ RKFTFWGXHYJYLXNWOTPKP RRPY[",
+ "H\\YIWGTFPFMGKIKKLMMNOOUQWRXSYUYXWZT[P[MZKX",
+ "JZRFR[ RKFYF",
+ "G]KFKULXNZQ[S[VZXXYUYF",
+ "I[JFR[ RZFR[",
+ "F^HFM[ RRFM[ RRFW[ R\\FW[",
+ "H\\KFY[ RYFK[",
+ "I[JFRPR[ RZFRP",
+ "H\\YFK[ RKFYF RK[Y[",
+ "KYOBOb RPBPb ROBVB RObVb",
+ "KYKFY^",
+ "KYTBTb RUBUb RNBUB RNbUb",
+ "JZRDJR RRDZR",
+ "I[Ib[b",
+ "NVSKQMQORPSORNQO",
+ "I\\XMX[ RXPVNTMQMONMPLSLUMXOZQ[T[VZXX",
+ "H[LFL[ RLPNNPMSMUNWPXSXUWXUZS[P[NZLX",
+ "I[XPVNTMQMONMPLSLUMXOZQ[T[VZXX",
+ "I\\XFX[ RXPVNTMQMONMPLSLUMXOZQ[T[VZXX",
+ "I[LSXSXQWOVNTMQMONMPLSLUMXOZQ[T[VZXX",
+ "MYWFUFSGRJR[ ROMVM",
+ "I\\XMX]W`VaTbQbOa RXPVNTMQMONMPLSLUMXOZQ[T[VZXX",
+ "I\\MFM[ RMQPNRMUMWNXQX[",
+ "NVQFRGSFREQF RRMR[",
+ "MWRFSGTFSERF RSMS^RaPbNb",
+ "IZMFM[ RWMMW RQSX[",
+ "NVRFR[",
+ "CaGMG[ RGQJNLMOMQNRQR[ RRQUNWMZM\\N]Q][",
+ "I\\MMM[ RMQPNRMUMWNXQX[",
+ "I\\QMONMPLSLUMXOZQ[T[VZXXYUYSXPVNTMQM",
+ "H[LMLb RLPNNPMSMUNWPXSXUWXUZS[P[NZLX",
+ "I\\XMXb RXPVNTMQMONMPLSLUMXOZQ[T[VZXX",
+ "KXOMO[ ROSPPRNTMWM",
+ "J[XPWNTMQMNNMPNRPSUTWUXWXXWZT[Q[NZMX",
+ "MYRFRWSZU[W[ ROMVM",
+ "I\\MMMWNZP[S[UZXW RXMX[",
+ "JZLMR[ RXMR[",
+ "G]JMN[ RRMN[ RRMV[ RZMV[",
+ "J[MMX[ RXMM[",
+ "JZLMR[ RXMR[P_NaLbKb",
+ "J[XMM[ RMMXM RM[X[",
+ "KYTBRCQDPFPHQJRKSMSOQQ RRCQEQGRISJTLTNSPORSTTVTXSZR[Q]Q_Ra RQSSU",
+ "NVRBRb",
+ "KYPBRCSDTFTHSJRKQMQOSQ RRCSESGRIQJPLPNQPURQTPVPXQZR[S]S_Ra RSSQU",
+ "F^IUISJPLONOPPTSVTXTZS[Q RISJQLPNPPQTTVUXUZT[Q[O",
+ "JZJFJ[K[KFLFL[M[MFNFN[O[OFPFP[Q[QFRFR[S[SFTFT[U[UFVFV[W[WFXFX[Y[YFZFZ["
+ }
+},
+{
+ "Rowman Double",
+ 0.040, /* X scale */
+ 0.040, /* Y scale */
+ 0.95, /* X spacing extra scale */
+ 0.08, /* Line width scale */
+ 0.0, /* horizontal offset */
+ 11.0, /* vertical offset */
+ {
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "MXRFRTST RRFSFST RRXQYQZR[S[TZTYSXRX RRYRZSZSYRY",
+ "I[NFMGMM RNGMM RNFOGMM RWFVGVM RWGVM RWFXGVM",
+ "H]SFLb RYFRb RLQZQ RKWYW",
+ "I\\RBR_S_ RRBSBS_ RWIYIWGTFQFNGLILKMMNNVRWSXUXWWYTZQZOYNX RWIVHTGQGNHMIMKNMVQXSYUYWXYWZT[Q[NZLXNX RXXUZ",
+ "F^[FI[ RNFPHPJOLMMKMIKIIJGLFNFPGSHVHYG[F RWTUUTWTYV[X[ZZ[X[VYTWT",
+ "F_\\MZMXNWPUVTXSYQZMZKYJWJUKSLRQOSMTKTISGQFPFNGMIMKNNPQUWXZZ[\\[ R\\M\\NZNXO RYNXPVVUXSZQ[M[KZJYIWIUJSLQQNRMSKSIRG RSHQGPGNH ROGNINKONQQVWXYZZ\\Z\\[",
+ "MXTHSIRIQHQGRFSFTGTJSLQM RRGRHSHSGRG RSITJ RTHSL",
+ "KYUBSDQGOKNPNTOYQ]S`UbVb RUBVBTDRGPKOPOTPYR]T`Vb",
+ "KYNBPDRGTKUPUTTYR]P`NbOb RNBOBQDSGUKVPVTUYS]Q`Ob",
+ "JZRFQGSQRR RRFRR RRFSGQQRR RMINIVOWO RMIWO RMIMJWNWO RWIVINOMO RWIMO RWIWJMNMO",
+ "F_RIRZSZ RRISISZ RJQ[Q[R RJQJR[R",
+ "MXTZS[R[QZQYRXSXTYT\\S^Q_ RRYRZSZSYRY RS[T\\ RTZS^",
+ "F_JQ[Q[R RJQJR[R",
+ "MXRXQYQZR[S[TZTYSXRX RRYRZSZSYRY",
+ "G^[BIbJb R[B\\BJb",
+ "H\\QFNGLJKOKRLWNZQ[S[VZXWYRYOXJVGSFQF ROGMJLOLRMWOZ RNYQZSZVY RUZWWXRXOWJUG RVHSGQGNH",
+ "H\\NJPISFS[ RNJNKPJRHR[S[",
+ "H\\LKLJMHNGPFTFVGWHXJXLWNUQL[ RLKMKMJNHPGTGVHWJWLVNTQK[ RLZYZY[ RK[Y[",
+ "H\\MFXFQO RMFMGWG RWFPO RQNSNVOXQYTYUXXVZS[P[MZLYKWLW RPOSOVPXS RTOWQXTXUWXTZ RXVVYSZPZMYLW ROZLX",
+ "H\\UIU[V[ RVFV[ RVFKVZV RUILV RLUZUZV",
+ "H\\MFLO RNGMN RMFWFWG RNGWG RMNPMSMVNXPYSYUXXVZS[P[MZLYKWLW RLOMOONSNVOXR RTNWPXSXUWXTZ RXVVYSZPZMYLW ROZLX",
+ "H\\VGWIXIWGTFRFOGMJLOLTMXOZR[S[VZXXYUYTXQVOSNRNOOMQ RWHTGRGOH RPGNJMOMTNXQZ RMVOYRZSZVYXV RTZWXXUXTWQTO RXSVPSOROOPMS RQONQMT",
+ "H\\KFYFO[ RKFKGXG RXFN[O[",
+ "H\\PFMGLILKMMNNPOTPVQWRXTXWWYTZPZMYLWLTMRNQPPTOVNWMXKXIWGTFPF RNGMIMKNMPNTOVPXRYTYWXYWZT[P[MZLYKWKTLRNPPOTNVMWKWIVG RWHTGPGMH RLXOZ RUZXX",
+ "H\\WPURRSQSNRLPKMKLLINGQFRFUGWIXMXRWWUZR[P[MZLXMXNZ RWMVPSR RWNUQRRQRNQLN RPRMPLMLLMIPG RLKNHQGRGUHWK RSGVIWMWRVWTZ RUYRZPZMY",
+ "MXRMQNQORPSPTOTNSMRM RRNROSOSNRN RRXQYQZR[S[TZTYSXRX RRYRZSZSYRY",
+ "MXRMQNQORPSPTOTNSMRM RRNROSOSNRN RTZS[R[QZQYRXSXTYT\\S^Q_ RRYRZSZSYRY RS[T\\ RTZS^",
+ "F^ZIJRZ[",
+ "F_JM[M[N RJMJN[N RJU[U[V RJUJV[V",
+ "F^JIZRJ[",
+ "I\\LKLJMHNGQFTFWGXHYJYLXNWOUPRQ RLKMKMJNHQGTGWHXJXLWNUORP RMIPG RUGXI RXMTP RRPRTSTSP RRXQYQZR[S[TZTYSXRX RRYRZSZSYRY",
+ "E`WNVLTKQKOLNMMPMSNUPVSVUUVS RQKOMNPNSOUPV RWKVSVUXVZV\\T]Q]O\\L[JYHWGTFQFNGLHJJILHOHRIUJWLYNZQ[T[WZYYZX RXKWSWUXV",
+ "H\\RFJ[ RRIK[J[ RRIY[Z[ RRFZ[ RMUWU RLVXV",
+ "H\\LFL[ RMGMZ RLFTFWGXHYJYMXOWPTQ RMGTGWHXJXMWOTP RMPTPWQXRYTYWXYWZT[L[ RMQTQWRXTXWWYTZMZ",
+ "H]ZKYIWGUFQFOGMILKKNKSLVMXOZQ[U[WZYXZV RZKYKXIWHUGQGOHMKLNLSMVOYQZUZWYXXYVZV",
+ "H]LFL[ RMGMZ RLFSFVGXIYKZNZSYVXXVZS[L[ RMGSGVHWIXKYNYSXVWXVYSZMZ",
+ "I\\MFM[ RNGNZ RMFYF RNGYGYF RNPTPTQ RNQTQ RNZYZY[ RM[Y[",
+ "I[MFM[ RNGN[M[ RMFYF RNGYGYF RNPTPTQ RNQTQ",
+ "H]ZKYIWGUFQFOGMILKKNKSLVMXOZQ[U[WZYXZVZRUR RZKYKXIWHUGQGOHNIMKLNLSMVNXOYQZUZWYXXYVYSUSUR",
+ "G]KFK[ RKFLFL[K[ RYFXFX[Y[ RYFY[ RLPXP RLQXQ",
+ "NWRFR[S[ RRFSFS[",
+ "J[VFVVUYSZQZOYNVMV RVFWFWVVYUZS[Q[OZNYMV",
+ "H]LFL[M[ RLFMFM[ RZFYFMR RZFMS RPOY[Z[ RQOZ[",
+ "IZMFM[ RMFNFNZ RNZYZY[ RM[Y[",
+ "F^JFJ[ RKKK[J[ RKKR[ RJFRX RZFRX RYKR[ RYKY[Z[ RZFZ[",
+ "G]KFK[ RLIL[K[ RLIY[ RKFXX RXFXX RXFYFY[",
+ "G]PFNGLIKKJNJSKVLXNZP[T[VZXXYVZSZNYKXIVGTFPF RQGNHLKKNKSLVNYQZSZVYXVYSYNXKVHSGQG",
+ "H\\LFL[ RMGM[L[ RLFUFWGXHYJYMXOWPUQMQ RMGUGWHXJXMWOUPMP",
+ "G]PFNGLIKKJNJSKVLXNZP[T[VZXXYVZSZNYKXIVGTFPF RQGNHLKKNKSLVNYQZSZVYXVYSYNXKVHSGQG RSXX]Y] RSXTXY]",
+ "H\\LFL[ RMGM[L[ RLFTFWGXHYJYMXOWPTQMQ RMGTGWHXJXMWOTPMP RRQX[Y[ RSQY[",
+ "H\\YIWGTFPFMGKIKKLMMNOOTQVRWSXUXXWYTZPZNYMXKX RYIWIVHTGPGMHLILKMMONTPVQXSYUYXWZT[P[MZKX",
+ "J[RGR[ RSGS[R[ RLFYFYG RLFLGYG",
+ "G]KFKULXNZQ[S[VZXXYUYF RKFLFLUMXNYQZSZVYWXXUXFYF",
+ "H\\JFR[ RJFKFRX RZFYFRX RZFR[",
+ "E_GFM[ RGFHFMX RRFMX RRIM[ RRIW[ RRFWX R]F\\FWX R]FW[",
+ "H\\KFX[Y[ RKFLFY[ RYFXFK[ RYFL[K[",
+ "I\\KFRPR[S[ RKFLFSP RZFYFRP RZFSPS[",
+ "H\\XFK[ RYFL[ RKFYF RKFKGXG RLZYZY[ RK[Y[",
+ "KYOBOb RPBPb ROBVB RObVb",
+ "KYKFY^",
+ "KYTBTb RUBUb RNBUB RNbUb",
+ "JZPLRITL RMORJWO RRJR[",
+ "JZJ]Z]",
+ "MXTFRGQIQLRMSMTLTKSJRJQK RRKRLSLSKRK RRGQK RQIRJ",
+ "H\\WMW[X[ RWMXMX[ RWPUNSMPMNNLPKSKULXNZP[S[UZWX RWPSNPNNOMPLSLUMXNYPZSZWX",
+ "H\\LFL[M[ RLFMFM[ RMPONQMTMVNXPYSYUXXVZT[Q[OZMX RMPQNTNVOWPXSXUWXVYTZQZMX",
+ "I[XPVNTMQMONMPLSLUMXOZQ[T[VZXX RXPWQVOTNQNOONPMSMUNXOYQZTZVYWWXX",
+ "H\\WFW[X[ RWFXFX[ RWPUNSMPMNNLPKSKULXNZP[S[UZWX RWPSNPNNOMPLSLUMXNYPZSZWX",
+ "I[MTXTXQWOVNTMQMONMPLSLUMXOZQ[T[VZXX RMSWSWQVOTNQNOONPMSMUNXOYQZTZVYWWXX",
+ "LZWFUFSGRJR[S[ RWFWGUGSH RTGSJS[ ROMVMVN ROMONVN",
+ "H\\XMWMW\\V_U`SaQaO`N_L_ RXMX\\W_UaSbPbNaL_ RWPUNSMPMNNLPKSKULXNZP[S[UZWX RWPSNPNNOMPLSLUMXNYPZSZWX",
+ "H\\LFL[M[ RLFMFM[ RMQPNRMUMWNXQX[ RMQPORNTNVOWQW[X[",
+ "NWRFQGQHRISITHTGSFRF RRGRHSHSGRG RRMR[S[ RRMSMS[",
+ "NWRFQGQHRISITHTGSFRF RRGRHSHSGRG RRMRbSb RRMSMSb",
+ "H[LFL[M[ RLFMFM[ RXMWMMW RXMMX RPTV[X[ RQSX[",
+ "NWRFR[S[ RRFSFS[",
+ "CbGMG[H[ RGMHMH[ RHQKNMMPMRNSQS[ RHQKOMNONQORQR[S[ RSQVNXM[M]N^Q^[ RSQVOXNZN\\O]Q][^[",
+ "H\\LML[M[ RLMMMM[ RMQPNRMUMWNXQX[ RMQPORNTNVOWQW[X[",
+ "I\\QMONMPLSLUMXOZQ[T[VZXXYUYSXPVNTMQM RQNOONPMSMUNXOYQZTZVYWXXUXSWPVOTNQN",
+ "H\\LMLbMb RLMMMMb RMPONQMTMVNXPYSYUXXVZT[Q[OZMX RMPQNTNVOWPXSXUWXVYTZQZMX",
+ "H\\WMWbXb RWMXMXb RWPUNSMPMNNLPKSKULXNZP[S[UZWX RWPSNPNNOMPLSLUMXNYPZSZWX",
+ "KYOMO[P[ ROMPMP[ RPSQPSNUMXM RPSQQSOUNXNXM",
+ "J[XPWNTMQMNNMPNRPSUUWV RVUWWWXVZ RWYTZQZNY ROZNXMX RXPWPVN RWOTNQNNO RONNPOR RNQPRUTWUXWXXWZT[Q[NZMX",
+ "MXRFR[S[ RRFSFS[ ROMVMVN ROMONVN",
+ "H\\LMLWMZO[R[TZWW RLMMMMWNYPZRZTYWW RWMW[X[ RWMXMX[",
+ "JZLMR[ RLMMMRY RXMWMRY RXMR[",
+ "F^IMN[ RIMJMNX RRMNX RRPN[ RRPV[ RRMVX R[MZMVX R[MV[",
+ "I[LMW[X[ RLMMMX[ RXMWML[ RXMM[L[",
+ "JZLMR[ RLMMMRY RXMWMRYNb RXMR[ObNb",
+ "I[VNL[ RXMNZ RLMXM RLMLNVN RNZXZX[ RL[X[",
+ "KYTBRCQDPFPHQJRKSMSOQQ RRCQEQGRISJTLTNSPORSTTVTXSZR[Q]Q_Ra RQSSUSWRYQZP\\P^Q`RaTb",
+ "NVRBRb",
+ "KYPBRCSDTFTHSJRKQMQOSQ RRCSESGRIQJPLPNQPURQTPVPXQZR[S]S_Ra RSSQUQWRYSZT\\T^S`RaPb",
+ "F^IUISJPLONOPPTSVTXTZS[Q RISJQLPNPPQTTVUXUZT[Q[O",
+ "KYQFOGNINKOMQNSNUMVKVIUGSFQF RQFNIOMSNVKUGQF RSFOGNKQNUMVISF"
+ }
+},
+{
+ "Rowman Triple",
+ 0.040, /* X scale */
+ 0.040, /* Y scale */
+ 0.96, /* X spacing extra scale */
+ 0.08, /* Line width scale */
+ 0.3, /* horizontal offset */
+ 11.0, /* vertical offset */
+ {
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "MXRFQGQIRQ RRFRTST RRFSFST RSFTGTISQ RRXQYQZR[S[TZTYSXRX RRYRZSZSYRY",
+ "I[NFMGMM RNGMM RNFOGMM RWFVGVM RWGVM RWFXGVM",
+ "H]SFLb RYFRb RLQZQ RKWYW",
+ "H\\PBP_ RTBT_ RXKXJWJWLYLYJXHWGTFPFMGKIKLLNOPURWSXUXXWZ RLLMNOOUQWRXT RMGLILKMMONUPXRYTYWXYWZT[P[MZLYKWKUMUMWLWLV",
+ "F^[FI[ RNFPHPJOLMMKMIKIIJGLFNFPGSHVHYG[F RWTUUTWTYV[X[ZZ[X[VYTWT",
+ "E_[O[NZNZP\\P\\N[MZMYNXPVUTXRZP[L[JZIXIUJSPORMSKSIRGPFNGMIMLNOPRTWWZY[[[\\Y\\X RKZJXJUKSLR RRMSI RSKRG RNGMK RNNPQTVWYYZ RN[LZKXKULSPO RMINMQQUVXYZZ[Z\\Y",
+ "MXTHSIRIQHQGRFSFTGTJSLQM RRGRHSHSGRG RSITJ RTHSL",
+ "KYUBSDQGOKNPNTOYQ]S`Ub RQHPKOOOUPYQ\\ RSDRFQIPOPUQ[R^S`",
+ "KYOBQDSGUKVPVTUYS]Q`Ob RSHTKUOUUTYS\\ RQDRFSITOTUS[R^Q`",
+ "JZRFQGSQRR RRFRR RRFSGQQRR RMINIVOWO RMIWO RMIMJWNWO RWIVINOMO RWIMO RWIWJMNMO",
+ "F_RIRZSZ RRISISZ RJQ[Q[R RJQJR[R",
+ "MXTZS[R[QZQYRXSXTYT\\S^Q_ RRYRZSZSYRY RS[T\\ RTZS^",
+ "F_JQ[Q[R RJQJR[R",
+ "MXRXQYQZR[S[TZTYSXRX RRYRZSZSYRY",
+ "G^[BIbJb R[B\\BJb",
+ "H\\QFNGLJKOKRLWNZQ[S[VZXWYRYOXJVGSFQF RNHMJLNLSMWNY RVYWWXSXNWJVH RQFOGNIMNMSNXOZQ[ RS[UZVXWSWNVIUGSF",
+ "H\\QHQ[ RRHRZ RSFS[ RSFPINJ RM[W[ RQZO[ RQYP[ RSYT[ RSZU[",
+ "H\\LJLKMKMJLJ RLIMINJNKMLLLKKKJLHMGPFTFWGXHYJYLXNUPPRNSLUKXK[ RWHXJXLWN RTFVGWJWLVNTPPR RKYLXNXSYWYYX RNXSZWZXY RNXS[W[XZYXYV",
+ "H\\LJLKMKMJLJ RLIMINJNKMLLLKKKJLHMGPFTFWGXIXLWNTO RVGWIWLVN RSFUGVIVLUNSO RQOTOVPXRYTYWXYWZT[P[MZLYKWKVLUMUNVNWMXLX RWRXTXWWY RSOUPVQWTWWVZT[ RLVLWMWMVLV",
+ "H\\SIS[ RTHTZ RUFU[ RUFJUZU RP[X[ RSZQ[ RSYR[ RUYV[ RUZW[",
+ "H\\MFKPMNPMSMVNXPYSYUXXVZS[P[MZLYKWKVLUMUNVNWMXLX RWPXRXVWX RSMUNVOWRWVVYUZS[ RLVLWMWMVLV RMFWF RMGUG RMHQHUGWF",
+ "H\\VIVJWJWIVI RWHVHUIUJVKWKXJXIWGUFRFOGMILKKOKULXNZQ[S[VZXXYUYTXQVOSNQNOONPMR RNIMKLOLUMXNY RWXXVXSWQ RRFPGOHNJMNMUNXOZQ[ RS[UZVYWVWSVPUOSN",
+ "H\\KFKL RYFYIXLTQSSRWR[ RSRRTQWQ[ RXLSQQTPWP[R[ RKJLHNFPFUIWIXHYF RMHNGPGRH RKJLINHPHUI",
+ "H\\PFMGLILLMNPOTOWNXLXIWGTFPF RNGMIMLNN RVNWLWIVG RPFOGNINLONPO RTOUNVLVIUGTF RPOMPLQKSKWLYMZP[T[WZXYYWYSXQWPTO RMQLSLWMY RWYXWXSWQ RPONPMSMWNZP[ RT[VZWWWSVPTO",
+ "H\\MWMXNXNWMW RWOVQURSSQSNRLPKMKLLINGQFSFVGXIYLYRXVWXUZR[O[MZLXLWMVNVOWOXNYMY RMPLNLKMI RVHWIXLXRWVVX RQSORNQMNMKNHOGQF RSFUGVIWLWSVWUYTZR[",
+ "MXRMQNQORPSPTOTNSMRM RRNROSOSNRN RRXQYQZR[S[TZTYSXRX RRYRZSZSYRY",
+ "MXRMQNQORPSPTOTNSMRM RRNROSOSNRN RTZS[R[QZQYRXSXTYT\\S^Q_ RRYRZSZSYRY RS[T\\ RTZS^",
+ "F^ZIJRZ[",
+ "F_JM[M[N RJMJN[N RJU[U[V RJUJV[V",
+ "F^JIZRJ[",
+ "I\\MKMJNJNLLLLJMHNGPFTFWGXHYJYLXNWOSQ RWHXIXMWN RTFVGWIWMVOUP RRQRTSTSQRQ RRXQYQZR[S[TZTYSXRX RRYRZSZSYRY",
+ "E`WNVLTKQKOLNMMPMSNUPVSVUUVS RQKOMNPNSOUPV RWKVSVUXVZV\\T]Q]O\\L[JYHWGTFQFNGLHJJILHOHRIUJWLYNZQ[T[WZYYZX RXKWSWUXV",
+ "H\\RFKZ RQIW[ RRIX[ RRFY[ RMUVU RI[O[ RT[[[ RKZJ[ RKZM[ RWZU[ RWYV[ RXYZ[",
+ "G]LFL[ RMGMZ RNFN[ RIFUFXGYHZJZLYNXOUP RXHYJYLXN RUFWGXIXMWOUP RNPUPXQYRZTZWYYXZU[I[ RXRYTYWXY RUPWQXSXXWZU[ RJFLG RKFLH ROFNH RPFNG RLZJ[ RLYK[ RNYO[ RNZP[",
+ "G\\XIYFYLXIVGTFQFNGLIKKJNJSKVLXNZQ[T[VZXXYV RMILKKNKSLVMX RQFOGMJLNLSMWOZQ[",
+ "G]LFL[ RMGMZ RNFN[ RIFSFVGXIYKZNZSYVXXVZS[I[ RWIXKYNYSXVWX RSFUGWJXNXSWWUZS[ RJFLG RKFLH ROFNH RPFNG RLZJ[ RLYK[ RNYO[ RNZP[",
+ "G\\LFL[ RMGMZ RNFN[ RIFYFYL RNPTP RTLTT RI[Y[YU RJFLG RKFLH ROFNH RPFNG RTFYG RVFYH RWFYI RXFYL RTLSPTT RTNRPTR RTOPPTQ RLZJ[ RLYK[ RNYO[ RNZP[ RT[YZ RV[YY RW[YX RX[YU",
+ "G[LFL[ RMGMZ RNFN[ RIFYFYL RNPTP RTLTT RI[Q[ RJFLG RKFLH ROFNH RPFNG RTFYG RVFYH RWFYI RXFYL RTLSPTT RTNRPTR RTOPPTQ RLZJ[ RLYK[ RNYO[ RNZP[",
+ "G^XIYFYLXIVGTFQFNGLIKKJNJSKVLXNZQ[T[VZXZY[YS RMILKKNKSLVMX RQFOGMJLNLSMWOZQ[ RXTXY RWSWYVZ RTS\\S RUSWT RVSWU RZSYU R[SYT",
+ "F^KFK[ RLGLZ RMFM[ RWFW[ RXGXZ RYFY[ RHFPF RTF\\F RMPWP RH[P[ RT[\\[ RIFKG RJFKH RNFMH ROFMG RUFWG RVFWH RZFYH R[FYG RKZI[ RKYJ[ RMYN[ RMZO[ RWZU[ RWYV[ RYYZ[ RYZ[[",
+ "LXQFQ[ RRGRZ RSFS[ RNFVF RN[V[ ROFQG RPFQH RTFSH RUFSG RQZO[ RQYP[ RSYT[ RSZU[",
+ "JYSFSWRZQ[ RTGTWSZ RUFUWTZQ[O[MZLXLVMUNUOVOWNXMX RMVMWNWNVMV RPFXF RQFSG RRFSH RVFUH RWFUG",
+ "F]KFK[ RLGLZ RMFM[ RXGMR RPPW[ RQPX[ RQNY[ RHFPF RUF[F RH[P[ RT[[[ RIFKG RJFKH RNFMH ROFMG RWFXG RZFXG RKZI[ RKYJ[ RMYN[ RMZO[ RWYU[ RWYZ[",
+ "I[NFN[ ROGOZ RPFP[ RKFSF RK[Z[ZU RLFNG RMFNH RQFPH RRFPG RNZL[ RNYM[ RPYQ[ RPZR[ RU[ZZ RW[ZY RX[ZX RY[ZU",
+ "E_JFJZ RJFQ[ RKFQX RLFRX RXFQ[ RXFX[ RYGYZ RZFZ[ RGFLF RXF]F RG[M[ RU[][ RHFJG R[FZH R\\FZG RJZH[ RJZL[ RXZV[ RXYW[ RZY[[ RZZ\\[",
+ "F^KFKZ RKFY[ RLFXX RMFYX RYGY[ RHFMF RVF\\F RH[N[ RIFKG RWFYG R[FYG RKZI[ RKZM[",
+ "G]QFNGLIKKJOJRKVLXNZQ[S[VZXXYVZRZOYKXIVGSFQF RMILKKNKSLVMX RWXXVYSYNXKWI RQFOGMJLNLSMWOZQ[ RS[UZWWXSXNWJUGSF",
+ "G]LFL[ RMGMZ RNFN[ RIFUFXGYHZJZMYOXPUQNQ RXHYJYMXO RUFWGXIXNWPUQ RI[Q[ RJFLG RKFLH ROFNH RPFNG RLZJ[ RLYK[ RNYO[ RNZP[",
+ "G]QFNGLIKKJOJRKVLXNZQ[S[VZXXYVZRZOYKXIVGSFQF RMILKKNKSLVMX RWXXVYSYNXKWI RQFOGMJLNLSMWOZQ[ RS[UZWWXSXNWJUGSF RNXOVQURUTVUXV^W`Y`Z^Z\\ RV\\W^X_Y_ RUXW]X^Y^Z]",
+ "G]LFL[ RMGMZ RNFN[ RIFUFXGYHZJZLYNXOUPNP RXHYJYLXN RUFWGXIXMWOUP RRPTQUSWYX[Z[[Y[W RWWXYYZZZ RTQURXXYYZY[X RI[Q[ RJFLG RKFLH ROFNH RPFNG RLZJ[ RLYK[ RNYO[ RNZP[",
+ "H\\XIYFYLXIVGSFPFMGKIKLLNOPURWSXUXXWZ RLLMNOOUQWRXT RMGLILKMMONUPXRYTYWXYWZT[Q[NZLXKUK[LX",
+ "H\\JFJL RQFQ[ RRGRZ RSFS[ RZFZL RJFZF RN[V[ RKFJL RLFJI RMFJH ROFJG RUFZG RWFZH RXFZI RYFZL RQZO[ RQYP[ RSYT[ RSZU[",
+ "F^KFKULXNZQ[S[VZXXYUYG RLGLVMX RMFMVNYOZQ[ RHFPF RVF\\F RIFKG RJFKH RNFMH ROFMG RWFYG R[FYG",
+ "H\\KFR[ RLFRXR[ RMFSX RYGR[ RIFPF RUF[F RJFLH RNFMH ROFMG RWFYG RZFYG",
+ "F^JFN[ RKFNVN[ RLFOV RRFOVN[ RRFV[ RSFVVV[ RTFWV RZGWVV[ RGFOF RRFTF RWF]F RHFKG RIFKH RMFLH RNFLG RXFZG R\\FZG",
+ "H\\KFW[ RLFX[ RMFY[ RXGLZ RIFPF RUF[F RI[O[ RT[[[ RJFMH RNFMH ROFMG RVFXG RZFXG RLZJ[ RLZN[ RWZU[ RWYV[ RWYZ[",
+ "G]JFQQQ[ RKFRQRZ RLFSQS[ RYGSQ RHFOF RVF\\F RN[V[ RIFKG RNFLG RWFYG R[FYG RQZO[ RQYP[ RSYT[ RSZU[",
+ "H\\YFKFKL RWFK[ RXFL[ RYFM[ RK[Y[YU RLFKL RMFKI RNFKH RPFKG RT[YZ RV[YY RW[YX RX[YU",
+ "KYOBOb RPBPb ROBVB RObVb",
+ "KYKFY^",
+ "KYTBTb RUBUb RNBUB RNbUb",
+ "JZPLRITL RMORJWO RRJR[",
+ "JZJ]Z]",
+ "MXTFRGQIQLRMSMTLTKSJRJQK RRKRLSLSKRK RRGQK RQIRJ",
+ "I]NPNOOOOQMQMONNPMTMVNWOXQXXYZZ[ RVOWQWXXZ RTMUNVPVXWZZ[[[ RVRUSPTMULWLXMZP[S[UZVX RNUMWMXNZ RUSQTOUNWNXOZP[",
+ "G\\LFL[MZOZ RMGMY RIFNFNZ RNPONQMSMVNXPYSYUXXVZS[Q[OZNX RWPXRXVWX RSMUNVOWRWVVYUZS[ RJFLG RKFLH",
+ "H[WQWPVPVRXRXPVNTMQMNNLPKSKULXNZQ[S[VZXX RMPLRLVMX RQMONNOMRMVNYOZQ[",
+ "H]VFV[[[ RWGWZ RSFXFX[ RVPUNSMQMNNLPKSKULXNZQ[S[UZVX RMPLRLVMX RQMONNOMRMVNYOZQ[ RTFVG RUFVH RXYY[ RXZZ[",
+ "H[MSXSXQWOVNSMQMNNLPKSKULXNZQ[S[VZXX RWRWQVO RMPLRLVMX RVSVPUNSM RQMONNOMRMVNYOZQ[",
+ "KYWHWGVGVIXIXGWFTFRGQHPKP[ RRHQKQZ RTFSGRIR[ RMMVM RM[U[ RPZN[ RPYO[ RRYS[ RRZT[",
+ "I\\XNYOZNYMXMVNUO RQMONNOMQMSNUOVQWSWUVVUWSWQVOUNSMQM ROONQNSOU RUUVSVQUO RQMPNOPOTPVQW RSWTVUTUPTNSM RNUMVLXLYM[N\\Q]U]X^Y_ RN[Q\\U\\X] RLYMZP[U[X\\Y^Y_XaUbObLaK_K^L\\O[ RObMaL_L^M\\O[",
+ "G^LFL[ RMGMZ RIFNFN[ RNQOOPNRMUMWNXOYRY[ RWOXRXZ RUMVNWQW[ RI[Q[ RT[\\[ RJFLG RKFLH RLZJ[ RLYK[ RNYO[ RNZP[ RWZU[ RWYV[ RYYZ[ RYZ[[",
+ "LXQFQHSHSFQF RRFRH RQGSG RQMQ[ RRNRZ RNMSMS[ RN[V[ ROMQN RPMQO RQZO[ RQYP[ RSYT[ RSZU[",
+ "KXRFRHTHTFRF RSFSH RRGTG RRMR^QaPb RSNS]R` ROMTMT]S`RaPbMbLaL_N_NaMaM` RPMRN RQMRO",
+ "G]LFL[ RMGMZ RIFNFN[ RWNNW RRSY[ RRTX[ RQTW[ RTM[M RI[Q[ RT[[[ RJFLG RKFLH RUMWN RZMWN RLZJ[ RLYK[ RNYO[ RNZP[ RWYU[ RVYZ[",
+ "LXQFQ[ RRGRZ RNFSFS[ RN[V[ ROFQG RPFQH RQZO[ RQYP[ RSYT[ RSZU[",
+ "AcFMF[ RGNGZ RCMHMH[ RHQIOJNLMOMQNROSRS[ RQORRRZ ROMPNQQQ[ RSQTOUNWMZM\\N]O^R^[ R\\O]R]Z RZM[N\\Q\\[ RC[K[ RN[V[ RY[a[ RDMFN REMFO RFZD[ RFYE[ RHYI[ RHZJ[ RQZO[ RQYP[ RSYT[ RSZU[ R\\ZZ[ R\\Y[[ R^Y_[ R^Z`[",
+ "G^LML[ RMNMZ RIMNMN[ RNQOOPNRMUMWNXOYRY[ RWOXRXZ RUMVNWQW[ RI[Q[ RT[\\[ RJMLN RKMLO RLZJ[ RLYK[ RNYO[ RNZP[ RWZU[ RWYV[ RYYZ[ RYZ[[",
+ "H\\QMNNLPKSKULXNZQ[S[VZXXYUYSXPVNSMQM RMPLRLVMX RWXXVXRWP RQMONNOMRMVNYOZQ[ RS[UZVYWVWRVOUNSM",
+ "G\\LMLb RMNMa RIMNMNb RNPONQMSMVNXPYSYUXXVZS[Q[OZNX RWPXRXVWX RSMUNVOWRWVVYUZS[ RIbQb RJMLN RKMLO RLaJb RL`Kb RN`Ob RNaPb",
+ "H\\VNVb RWOWa RUNWNXMXb RVPUNSMQMNNLPKSKULXNZQ[S[UZVX RMPLRLVMX RQMONNOMRMVNYOZQ[ RSb[b RVaTb RV`Ub RX`Yb RXaZb",
+ "IZNMN[ RONOZ RKMPMP[ RWOWNVNVPXPXNWMUMSNQPPS RK[S[ RLMNN RMMNO RNZL[ RNYM[ RPYQ[ RPZR[",
+ "J[WOXMXQWOVNTMPMNNMOMQNSPTUUWVXY RNNMQ RNRPSUTWU RXVWZ RMONQPRUSWTXVXYWZU[Q[OZNYMWM[NY",
+ "KZPHPVQYRZT[V[XZYX RQHQWRY RPHRFRWSZT[ RMMVM",
+ "G^LMLVMYNZP[S[UZVYWW RMNMWNY RIMNMNWOZP[ RWMW[\\[ RXNXZ RTMYMY[ RJMLN RKMLO RYYZ[ RYZ[[",
+ "I[LMR[ RMMRY RNMSY RXNSYR[ RJMQM RTMZM RKMNO RPMNN RVMXN RYMXN",
+ "F^JMN[ RKMNX RLMOX RRMOXN[ RRMV[ RSMVX RRMTMWX RZNWXV[ RGMOM RWM]M RHMKN RNMLN RXMZN R\\MZN",
+ "H\\LMV[ RMMW[ RNMX[ RWNMZ RJMQM RTMZM RJ[P[ RS[Z[ RKMMN RPMNN RUMWN RYMWN RMZK[ RMZO[ RVZT[ RWZY[",
+ "H[LMR[ RMMRY RNMSY RXNSYP_NaLbJbIaI_K_KaJaJ` RJMQM RTMZM RKMNO RPMNN RVMXN RYMXN",
+ "I[VML[ RWMM[ RXMN[ RXMLMLQ RL[X[XW RMMLQ RNMLP ROMLO RQMLN RS[XZ RU[XY RV[XX RW[XW",
+ "KYTBRCQDPFPHQJRKSMSOQQ RRCQEQGRISJTLTNSPORSTTVTXSZR[Q]Q_Ra RQSSUSWRYQZP\\P^Q`RaTb",
+ "NVRBRb",
+ "KYPBRCSDTFTHSJRKQMQOSQ RRCSESGRIQJPLPNQPURQTPVPXQZR[S]S_Ra RSSQUQWRYSZT\\T^S`RaPb",
+ "F^IUISJPLONOPPTSVTXTZS[Q RISJQLPNPPQTTVUXUZT[Q[O",
+ "KYQFOGNINKOMQNSNUMVKVIUGSFQF RQFNIOMSNVKUGQF RSFOGNKQNUMVISF"
+ }
+},
+{
+ "Times Roman",
+ 0.041, /* X scale */
+ 0.041, /* Y scale */
+ 0.95, /* X spacing extra scale */
+ 0.055, /* Line width scale */
+ 0.0, /* horizontal offset */
+ 10.5, /* vertical offset */
+ {
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "MWRFQHRTSHRF RRHRN RRYQZR[SZRY",
+ "I[NFMGMM RNGMM RNFOGMM RWFVGVM RWGVM RWFXGVM",
+ "H]SBLb RYBRb RLOZO RKUYU",
+ "H\\PBP_ RTBT_ RXIWJXKYJYIWGTFPFMGKIKKLMMNOOUQWRYT RKKMMONUPWQXRYTYXWZT[P[MZKXKWLVMWLX",
+ "F^[FI[ RNFPHPJOLMMKMIKIIJGLFNFPGSHVHYG[F RWTUUTWTYV[X[ZZ[X[VYTWT",
+ "F_[NZO[P\\O\\N[MZMYNXPVUTXRZP[M[JZIXIUJSPORMSKSIRGPFNGMIMKNNPQUXWZZ[[[\\Z\\Y RM[KZJXJUKSMQ RMKNMVXXZZ[",
+ "NVRFQM RSFQM",
+ "KYVBTDRGPKOPOTPYR]T`Vb RTDRHQKPPPTQYR\\T`",
+ "KYNBPDRGTKUPUTTYR]P`Nb RPDRHSKTPTTSYR\\P`",
+ "JZRLRX RMOWU RWOMU",
+ "E_RIR[ RIR[R",
+ "NVSWRXQWRVSWSYQ[",
+ "E_IR[R",
+ "NVRVQWRXSWRV",
+ "G][BIb",
+ "H\\QFNGLJKOKRLWNZQ[S[VZXWYRYOXJVGSFQF RQFOGNHMJLOLRMWNYOZQ[ RS[UZVYWWXRXOWJVHUGSF",
+ "H\\NJPISFS[ RRGR[ RN[W[",
+ "H\\LJMKLLKKKJLHMGPFTFWGXHYJYLXNUPPRNSLUKXK[ RTFVGWHXJXLWNTPPR RKYLXNXSZVZXYYX RNXS[W[XZYXYV",
+ "H\\LJMKLLKKKJLHMGPFTFWGXIXLWNTOQO RTFVGWIWLVNTO RTOVPXRYTYWXYWZT[P[MZLYKWKVLUMVLW RWQXTXWWYVZT[",
+ "H\\THT[ RUFU[ RUFJUZU RQ[X[",
+ "H\\MFKP RKPMNPMSMVNXPYSYUXXVZS[P[MZLYKWKVLUMVLW RSMUNWPXSXUWXUZS[ RMFWF RMGRGWF",
+ "H\\WIVJWKXJXIWGUFRFOGMILKKOKULXNZQ[S[VZXXYUYTXQVOSNRNOOMQLT RRFPGNIMKLOLUMXOZQ[ RS[UZWXXUXTWQUOSN",
+ "H\\KFKL RKJLHNFPFUIWIXHYF RLHNGPGUI RYFYIXLTQSSRVR[ RXLSQRSQVQ[",
+ "H\\PFMGLILLMNPOTOWNXLXIWGTFPF RPFNGMIMLNNPO RTOVNWLWIVGTF RPOMPLQKSKWLYMZP[T[WZXYYWYSXQWPTO RPONPMQLSLWMYNZP[ RT[VZWYXWXSWQVPTO",
+ "H\\XMWPURRSQSNRLPKMKLLINGQFSFVGXIYLYRXVWXUZR[O[MZLXLWMVNWMX RQSORMPLMLLMIOGQF RSFUGWIXLXRWVVXTZR[",
+ "NVROQPRQSPRO RRVQWRXSWRV",
+ "NVROQPRQSPRO RSWRXQWRVSWSYQ[",
+ "F^ZIJRZ[",
+ "E_IO[O RIU[U",
+ "F^JIZRJ[",
+ "I[MJNKMLLKLJMHNGPFSFVGWHXJXLWNVORQRT RSFUGVHWJWLVNTP RRYQZR[SZRY",
+ "E`WNVLTKQKOLNMMPMSNUPVSVUUVS RQKOMNPNSOUPV RWKVSVUXVZV\\T]Q]O\\L[JYHWGTFQFNGLHJJILHOHRIUJWLYNZQ[T[WZYYZX RXKWSWUXV",
+ "H\\RFK[ RRFY[ RRIX[ RMUVU RI[O[ RU[[[",
+ "G]LFL[ RMFM[ RIFUFXGYHZJZLYNXOUP RUFWGXHYJYLXNWOUP RMPUPXQYRZTZWYYXZU[I[ RUPWQXRYTYWXYWZU[",
+ "G\\XIYLYFXIVGSFQFNGLIKKJNJSKVLXNZQ[S[VZXXYV RQFOGMILKKNKSLVMXOZQ[",
+ "G]LFL[ RMFM[ RIFSFVGXIYKZNZSYVXXVZS[I[ RSFUGWIXKYNYSXVWXUZS[",
+ "G\\LFL[ RMFM[ RSLST RIFYFYLXF RMPSP RI[Y[YUX[",
+ "G[LFL[ RMFM[ RSLST RIFYFYLXF RMPSP RI[P[",
+ "G^XIYLYFXIVGSFQFNGLIKKJNJSKVLXNZQ[S[VZXX RQFOGMILKKNKSLVMXOZQ[ RXSX[ RYSY[ RUS\\S",
+ "F^KFK[ RLFL[ RXFX[ RYFY[ RHFOF RUF\\F RLPXP RH[O[ RU[\\[",
+ "MXRFR[ RSFS[ ROFVF RO[V[",
+ "KZUFUWTZR[P[NZMXMVNUOVNW RTFTWSZR[ RQFXF",
+ "F\\KFK[ RLFL[ RYFLS RQOY[ RPOX[ RHFOF RUF[F RH[O[ RU[[[",
+ "I[NFN[ ROFO[ RKFRF RK[Z[ZUY[",
+ "F_KFK[ RLFRX RKFR[ RYFR[ RYFY[ RZFZ[ RHFLF RYF]F RH[N[ RV[][",
+ "G^LFL[ RMFYY RMHY[ RYFY[ RIFMF RVF\\F RI[O[",
+ "G]QFNGLIKKJOJRKVLXNZQ[S[VZXXYVZRZOYKXIVGSFQF RQFOGMILKKOKRLVMXOZQ[ RS[UZWXXVYRYOXKWIUGSF",
+ "G]LFL[ RMFM[ RIFUFXGYHZJZMYOXPUQMQ RUFWGXHYJYMXOWPUQ RI[P[",
+ "G]QFNGLIKKJOJRKVLXNZQ[S[VZXXYVZRZOYKXIVGSFQF RQFOGMILKKOKRLVMXOZQ[ RS[UZWXXVYRYOXKWIUGSF RNYNXOVQURUTVUXV_W`Y`Z^Z] RUXV\\W^X_Y_Z^",
+ "G]LFL[ RMFM[ RIFUFXGYHZJZLYNXOUPMP RUFWGXHYJYLXNWOUP RI[P[ RRPTQURXYYZZZ[Y RTQUSWZX[Z[[Y[X",
+ "H\\XIYFYLXIVGSFPFMGKIKKLMMNOOUQWRYT RKKMMONUPWQXRYTYXWZT[Q[NZLXKUK[LX",
+ "I\\RFR[ RSFS[ RLFKLKFZFZLYF RO[V[",
+ "F^KFKULXNZQ[S[VZXXYUYF RLFLUMXOZQ[ RHFOF RVF\\F",
+ "H\\KFR[ RLFRX RYFR[ RIFOF RUF[F",
+ "F^JFN[ RKFNV RRFN[ RRFV[ RSFVV RZFV[ RGFNF RWF]F",
+ "H\\KFX[ RLFY[ RYFK[ RIFOF RUF[F RI[O[ RU[[[",
+ "H]KFRQR[ RLFSQS[ RZFSQ RIFOF RVF\\F RO[V[",
+ "H\\XFK[ RYFL[ RLFKLKFYF RK[Y[YUX[",
+ "KYOBOb RPBPb ROBVB RObVb",
+ "KYKFY^",
+ "KYTBTb RUBUb RNBUB RNbUb",
+ "G]JTROZT RJTRPZT",
+ "H\\Hb\\b",
+ "LXPFUL RPFOGUL",
+ "I]NONPMPMONNPMTMVNWOXQXXYZZ[ RWOWXXZZ[[[ RWQVRPSMTLVLXMZP[S[UZWX RPSNTMVMXNZP[",
+ "G\\LFL[ RMFM[ RMPONQMSMVNXPYSYUXXVZS[Q[OZMX RSMUNWPXSXUWXUZS[ RIFMF",
+ "H[WPVQWRXQXPVNTMQMNNLPKSKULXNZQ[S[VZXX RQMONMPLSLUMXOZQ[",
+ "H]WFW[ RXFX[ RWPUNSMQMNNLPKSKULXNZQ[S[UZWX RQMONMPLSLUMXOZQ[ RTFXF RW[[[",
+ "H[LSXSXQWOVNTMQMNNLPKSKULXNZQ[S[VZXX RWSWPVN RQMONMPLSLUMXOZQ[",
+ "KXUGTHUIVHVGUFSFQGPIP[ RSFRGQIQ[ RMMUM RM[T[",
+ "I\\QMONNOMQMSNUOVQWSWUVVUWSWQVOUNSMQM RONNPNTOV RUVVTVPUN RVOWNYMYNWN RNUMVLXLYM[P\\U\\X]Y^ RLYMZP[U[X\\Y^Y_XaUbObLaK_K^L\\O[",
+ "G]LFL[ RMFM[ RMPONRMTMWNXPX[ RTMVNWPW[ RIFMF RI[P[ RT[[[",
+ "MXRFQGRHSGRF RRMR[ RSMS[ ROMSM RO[V[",
+ "MXSFRGSHTGSF RTMT_SaQbObNaN`O_P`Oa RSMS_RaQb RPMTM",
+ "G\\LFL[ RMFM[ RWMMW RRSX[ RQSW[ RIFMF RTMZM RI[P[ RT[Z[",
+ "MXRFR[ RSFS[ ROFSF RO[V[",
+ "BcGMG[ RHMH[ RHPJNMMOMRNSPS[ ROMQNRPR[ RSPUNXMZM]N^P^[ RZM\\N]P][ RDMHM RD[K[ RO[V[ RZ[a[",
+ "G]LML[ RMMM[ RMPONRMTMWNXPX[ RTMVNWPW[ RIMMM RI[P[ RT[[[",
+ "H\\QMNNLPKSKULXNZQ[S[VZXXYUYSXPVNSMQM RQMONMPLSLUMXOZQ[ RS[UZWXXUXSWPUNSM",
+ "G\\LMLb RMMMb RMPONQMSMVNXPYSYUXXVZS[Q[OZMX RSMUNWPXSXUWXUZS[ RIMMM RIbPb",
+ "H\\WMWb RXMXb RWPUNSMQMNNLPKSKULXNZQ[S[UZWX RQMONMPLSLUMXOZQ[ RTb[b",
+ "IZNMN[ ROMO[ ROSPPRNTMWMXNXOWPVOWN RKMOM RK[R[",
+ "J[WOXMXQWOVNTMPMNNMOMQNRPSUUWVXW RMPNQPRUTWUXVXYWZU[Q[OZNYMWM[NY",
+ "KZPFPWQZS[U[WZXX RQFQWRZS[ RMMUM",
+ "G]LMLXMZP[R[UZWX RMMMXNZP[ RWMW[ RXMX[ RIMMM RTMXM RW[[[",
+ "I[LMR[ RMMRY RXMR[ RJMPM RTMZM",
+ "F^JMN[ RKMNX RRMN[ RRMV[ RSMVX RZMV[ RGMNM RWM]M",
+ "H\\LMW[ RMMX[ RXML[ RJMPM RTMZM RJ[P[ RT[Z[",
+ "H[LMR[ RMMRY RXMR[P_NaLbKbJaK`La RJMPM RTMZM",
+ "I[WML[ RXMM[ RMMLQLMXM RL[X[XWW[",
+ "KYTBRCQDPFPHQJRKSMSOQQ RRCQEQGRISJTLTNSPORSTTVTXSZR[Q]Q_Ra RQSSUSWRYQZP\\P^Q`RaTb",
+ "NVRBRb",
+ "KYPBRCSDTFTHSJRKQMQOSQ RRCSESGRIQJPLPNQPURQTPVPXQZR[S]S_Ra RSSQUQWRYSZT\\T^S`RaPb",
+ "F^IUISJPLONOPPTSVTXTZS[Q RISJQLPNPPQTTVUXUZT[Q[O",
+ "JZJFJ[K[KFLFL[M[MFNFN[O[OFPFP[Q[QFRFR[S[SFTFT[U[UFVFV[W[WFXFX[Y[YFZFZ["
+ }
+},
+{
+ "Times Roman Bold",
+ 0.041, /* X scale */
+ 0.041, /* Y scale */
+ 0.95, /* X spacing extra scale */
+ 0.055, /* Line width scale */
+ 0.0, /* horizontal offset */
+ 10.5, /* vertical offset */
+ {
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "MXRFQGQIRQ RRFRTST RRFSFST RSFTGTISQ RRXQYQZR[S[TZTYSXRX RRYRZSZSYRY",
+ "I[NFMGMM RNGMM RNFOGMM RWFVGVM RWGVM RWFXGVM",
+ "H]SBLb RYBRb RLOZO RKUYU",
+ "H\\PBP_ RTBT_ RXKXJWJWLYLYJXHWGTFPFMGKIKLLNOPURWSXUXXWZ RLLMNOOUQWRXT RMGLILKMMONUPXRYTYWXYWZT[P[MZLYKWKUMUMWLWLV",
+ "F^[FI[ RNFPHPJOLMMKMIKIIJGLFNFPGSHVHYG[F RWTUUTWTYV[X[ZZ[X[VYTWT",
+ "E_[O[NZNZP\\P\\N[MZMYNXPVUTXRZP[L[JZIXIUJSPORMSKSIRGPFNGMIMLNOPRTWWZY[[[\\Y\\X RKZJXJUKSLR RRMSI RSKRG RNGMK RNNPQTVWYYZ RN[LZKXKULSPO RMINMQQUVXYZZ[Z\\Y",
+ "NWSFRGRM RSGRM RSFTGRM",
+ "KYUBSDQGOKNPNTOYQ]S`Ub RQHPKOOOUPYQ\\ RSDRFQIPOPUQ[R^S`",
+ "KYOBQDSGUKVPVTUYS]Q`Ob RSHTKUOUUTYS\\ RQDRFSITOTUS[R^Q`",
+ "JZRFQGSQRR RRFRR RRFSGQQRR RMINIVOWO RMIWO RMIMJWNWO RWIVINOMO RWIMO RWIWJMNMO",
+ "F_RIRZSZ RRISISZ RJQ[Q[R RJQJR[R",
+ "MXTZS[R[QZQYRXSXTYT\\S^Q_ RRYRZSZSYRY RS[T\\ RTZS^",
+ "E_IR[R",
+ "MXRXQYQZR[S[TZTYSXRX RRYRZSZSYRY",
+ "G^[BIbJb R[B\\BJb",
+ "H\\QFNGLJKOKRLWNZQ[S[VZXWYRYOXJVGSFQF RNHMJLNLSMWNY RVYWWXSXNWJVH RQFOGNIMNMSNXOZQ[ RS[UZVXWSWNVIUGSF",
+ "H\\QHQ[ RRHRZ RSFS[ RSFPINJ RM[W[ RQZO[ RQYP[ RSYT[ RSZU[",
+ "H\\LJLKMKMJLJ RLIMINJNKMLLLKKKJLHMGPFTFWGXHYJYLXNUPPRNSLUKXK[ RWHXJXLWN RTFVGWJWLVNTPPR RKYLXNXSYWYYX RNXSZWZXY RNXS[W[XZYXYV",
+ "H\\LJLKMKMJLJ RLIMINJNKMLLLKKKJLHMGPFTFWGXIXLWNTO RVGWIWLVN RSFUGVIVLUNSO RQOTOVPXRYTYWXYWZT[P[MZLYKWKVLUMUNVNWMXLX RWRXTXWWY RSOUPVQWTWWVZT[ RLVLWMWMVLV",
+ "H\\SIS[ RTHTZ RUFU[ RUFJUZU RP[X[ RSZQ[ RSYR[ RUYV[ RUZW[",
+ "H\\MFKPMNPMSMVNXPYSYUXXVZS[P[MZLYKWKVLUMUNVNWMXLX RWPXRXVWX RSMUNVOWRWVVYUZS[ RLVLWMWMVLV RMFWF RMGUG RMHQHUGWF",
+ "H\\VIVJWJWIVI RWHVHUIUJVKWKXJXIWGUFRFOGMILKKOKULXNZQ[S[VZXXYUYTXQVOSNQNOONPMR RNIMKLOLUMXNY RWXXVXSWQ RRFPGOHNJMNMUNXOZQ[ RS[UZVYWVWSVPUOSN",
+ "H\\KFKL RYFYIXLTQSSRWR[ RSRRTQWQ[ RXLSQQTPWP[R[ RKJLHNFPFUIWIXHYF RMHNGPGRH RKJLINHPHUI",
+ "H\\PFMGLILLMNPOTOWNXLXIWGTFPF RNGMIMLNN RVNWLWIVG RPFOGNINLONPO RTOUNVLVIUGTF RPOMPLQKSKWLYMZP[T[WZXYYWYSXQWPTO RMQLSLWMY RWYXWXSWQ RPONPMSMWNZP[ RT[VZWWWSVPTO",
+ "H\\MWMXNXNWMW RWOVQURSSQSNRLPKMKLLINGQFSFVGXIYLYRXVWXUZR[O[MZLXLWMVNVOWOXNYMY RMPLNLKMI RVHWIXLXRWVVX RQSORNQMNMKNHOGQF RSFUGVIWLWSVWUYTZR[",
+ "MXRMQNQORPSPTOTNSMRM RRNROSOSNRN RRXQYQZR[S[TZTYSXRX RRYRZSZSYRY",
+ "MXRMQNQORPSPTOTNSMRM RRNROSOSNRN RTZS[R[QZQYRXSXTYT\\S^Q_ RRYRZSZSYRY RS[T\\ RTZS^",
+ "F^ZIJRZ[",
+ "F_JM[M[N RJMJN[N RJU[U[V RJUJV[V",
+ "F^JIZRJ[",
+ "I\\MKMJNJNLLLLJMHNGPFTFWGXHYJYLXNWOSQ RWHXIXMWN RTFVGWIWMVOUP RRQRTSTSQRQ RRXQYQZR[S[TZTYSXRX RRYRZSZSYRY",
+ "E`WNVLTKQKOLNMMPMSNUPVSVUUVS RQKOMNPNSOUPV RWKVSVUXVZV\\T]Q]O\\L[JYHWGTFQFNGLHJJILHOHRIUJWLYNZQ[T[WZYYZX RXKWSWUXV",
+ "H\\RFKZ RQIW[ RRIX[ RRFY[ RMUVU RI[O[ RT[[[ RKZJ[ RKZM[ RWZU[ RWYV[ RXYZ[",
+ "G]LFL[ RMGMZ RNFN[ RIFUFXGYHZJZLYNXOUP RXHYJYLXN RUFWGXIXMWOUP RNPUPXQYRZTZWYYXZU[I[ RXRYTYWXY RUPWQXSXXWZU[ RJFLG RKFLH ROFNH RPFNG RLZJ[ RLYK[ RNYO[ RNZP[",
+ "G\\XIYFYLXIVGTFQFNGLIKKJNJSKVLXNZQ[T[VZXXYV RMILKKNKSLVMX RQFOGMJLNLSMWOZQ[",
+ "G]LFL[ RMGMZ RNFN[ RIFSFVGXIYKZNZSYVXXVZS[I[ RWIXKYNYSXVWX RSFUGWJXNXSWWUZS[ RJFLG RKFLH ROFNH RPFNG RLZJ[ RLYK[ RNYO[ RNZP[",
+ "G\\LFL[ RMGMZ RNFN[ RIFYFYL RNPTP RTLTT RI[Y[YU RJFLG RKFLH ROFNH RPFNG RTFYG RVFYH RWFYI RXFYL RTLSPTT RTNRPTR RTOPPTQ RLZJ[ RLYK[ RNYO[ RNZP[ RT[YZ RV[YY RW[YX RX[YU",
+ "G[LFL[ RMGMZ RNFN[ RIFYFYL RNPTP RTLTT RI[Q[ RJFLG RKFLH ROFNH RPFNG RTFYG RVFYH RWFYI RXFYL RTLSPTT RTNRPTR RTOPPTQ RLZJ[ RLYK[ RNYO[ RNZP[",
+ "G^XIYFYLXIVGTFQFNGLIKKJNJSKVLXNZQ[T[VZXZY[YS RMILKKNKSLVMX RQFOGMJLNLSMWOZQ[ RXTXY RWSWYVZ RTS\\S RUSWT RVSWU RZSYU R[SYT",
+ "F^KFK[ RLGLZ RMFM[ RWFW[ RXGXZ RYFY[ RHFPF RTF\\F RMPWP RH[P[ RT[\\[ RIFKG RJFKH RNFMH ROFMG RUFWG RVFWH RZFYH R[FYG RKZI[ RKYJ[ RMYN[ RMZO[ RWZU[ RWYV[ RYYZ[ RYZ[[",
+ "LXQFQ[ RRGRZ RSFS[ RNFVF RN[V[ ROFQG RPFQH RTFSH RUFSG RQZO[ RQYP[ RSYT[ RSZU[",
+ "JZSFSWRZQ[ RTGTWSZ RUFUWTZQ[O[MZLXLVMUNUOVOWNXMX RMVMWNWNVMV RPFXF RQFSG RRFSH RVFUH RWFUG",
+ "F\\KFK[ RLGLZ RMFM[ RXGMR RPPW[ RQPX[ RQNY[ RHFPF RUF[F RH[P[ RT[[[ RIFKG RJFKH RNFMH ROFMG RWFXG RZFXG RKZI[ RKYJ[ RMYN[ RMZO[ RWYU[ RWYZ[",
+ "I[NFN[ ROGOZ RPFP[ RKFSF RK[Z[ZU RLFNG RMFNH RQFPH RRFPG RNZL[ RNYM[ RPYQ[ RPZR[ RU[ZZ RW[ZY RX[ZX RY[ZU",
+ "E_JFJZ RJFQ[ RKFQX RLFRX RXFQ[ RXFX[ RYGYZ RZFZ[ RGFLF RXF]F RG[M[ RU[][ RHFJG R[FZH R\\FZG RJZH[ RJZL[ RXZV[ RXYW[ RZY[[ RZZ\\[",
+ "F^KFKZ RKFY[ RLFXX RMFYX RYGY[ RHFMF RVF\\F RH[N[ RIFKG RWFYG R[FYG RKZI[ RKZM[",
+ "G]QFNGLIKKJOJRKVLXNZQ[S[VZXXYVZRZOYKXIVGSFQF RMILKKNKSLVMX RWXXVYSYNXKWI RQFOGMJLNLSMWOZQ[ RS[UZWWXSXNWJUGSF",
+ "G]LFL[ RMGMZ RNFN[ RIFUFXGYHZJZMYOXPUQNQ RXHYJYMXO RUFWGXIXNWPUQ RI[Q[ RJFLG RKFLH ROFNH RPFNG RLZJ[ RLYK[ RNYO[ RNZP[",
+ "G]QFNGLIKKJOJRKVLXNZQ[S[VZXXYVZRZOYKXIVGSFQF RMILKKNKSLVMX RWXXVYSYNXKWI RQFOGMJLNLSMWOZQ[ RS[UZWWXSXNWJUGSF RNXOVQURUTVUXV^W`Y`Z^Z\\ RV\\W^X_Y_ RUXW]X^Y^Z]",
+ "G]LFL[ RMGMZ RNFN[ RIFUFXGYHZJZLYNXOUPNP RXHYJYLXN RUFWGXIXMWOUP RRPTQUSWYX[Z[[Y[W RWWXYYZZZ RTQURXXYYZY[X RI[Q[ RJFLG RKFLH ROFNH RPFNG RLZJ[ RLYK[ RNYO[ RNZP[",
+ "H\\XIYFYLXIVGSFPFMGKIKLLNOPURWSXUXXWZ RLLMNOOUQWRXT RMGLILKMMONUPXRYTYWXYWZT[Q[NZLXKUK[LX",
+ "H\\JFJL RQFQ[ RRGRZ RSFS[ RZFZL RJFZF RN[V[ RKFJL RLFJI RMFJH ROFJG RUFZG RWFZH RXFZI RYFZL RQZO[ RQYP[ RSYT[ RSZU[",
+ "F^KFKULXNZQ[S[VZXXYUYG RLGLVMX RMFMVNYOZQ[ RHFPF RVF\\F RIFKG RJFKH RNFMH ROFMG RWFYG R[FYG",
+ "H\\KFR[ RLFRXR[ RMFSX RYGR[ RIFPF RUF[F RJFLH RNFMH ROFMG RWFYG RZFYG",
+ "F^JFN[ RKFNVN[ RLFOV RRFOVN[ RRFV[ RSFVVV[ RTFWV RZGWVV[ RGFOF RRFTF RWF]F RHFKG RIFKH RMFLH RNFLG RXFZG R\\FZG",
+ "H\\KFW[ RLFX[ RMFY[ RXGLZ RIFPF RUF[F RI[O[ RT[[[ RJFMH RNFMH ROFMG RVFXG RZFXG RLZJ[ RLZN[ RWZU[ RWYV[ RWYZ[",
+ "G]JFQQQ[ RKFRQRZ RLFSQS[ RYGSQ RHFOF RVF\\F RN[V[ RIFKG RNFLG RWFYG R[FYG RQZO[ RQYP[ RSYT[ RSZU[",
+ "H\\YFKFKL RWFK[ RXFL[ RYFM[ RK[Y[YU RLFKL RMFKI RNFKH RPFKG RT[YZ RV[YY RW[YX RX[YU",
+ "KYOBOb RPBPb ROBVB RObVb",
+ "KYKFY^",
+ "KYTBTb RUBUb RNBUB RNbUb",
+ "G]JTROZT RJTRPZT",
+ "H\\Hb\\b",
+ "LXPFUL RPFOGUL",
+ "I]NPNOOOOQMQMONNPMTMVNWOXQXXYZZ[ RVOWQWXXZ RTMUNVPVXWZZ[[[ RVRUSPTMULWLXMZP[S[UZVX RNUMWMXNZ RUSQTOUNWNXOZP[",
+ "G\\LFL[MZOZ RMGMY RIFNFNZ RNPONQMSMVNXPYSYUXXVZS[Q[OZNX RWPXRXVWX RSMUNVOWRWVVYUZS[ RJFLG RKFLH",
+ "H[WQWPVPVRXRXPVNTMQMNNLPKSKULXNZQ[S[VZXX RMPLRLVMX RQMONNOMRMVNYOZQ[",
+ "H]VFV[[[ RWGWZ RSFXFX[ RVPUNSMQMNNLPKSKULXNZQ[S[UZVX RMPLRLVMX RQMONNOMRMVNYOZQ[ RTFVG RUFVH RXYY[ RXZZ[",
+ "H[MSXSXQWOVNSMQMNNLPKSKULXNZQ[S[VZXX RWRWQVO RMPLRLVMX RVSVPUNSM RQMONNOMRMVNYOZQ[",
+ "KYWHWGVGVIXIXGWFTFRGQHPKP[ RRHQKQZ RTFSGRIR[ RMMVM RM[U[ RPZN[ RPYO[ RRYS[ RRZT[",
+ "I\\XNYOZNYMXMVNUO RQMONNOMQMSNUOVQWSWUVVUWSWQVOUNSMQM ROONQNSOU RUUVSVQUO RQMPNOPOTPVQW RSWTVUTUPTNSM RNUMVLXLYM[N\\Q]U]X^Y_ RN[Q\\U\\X] RLYMZP[U[X\\Y^Y_XaUbObLaK_K^L\\O[ RObMaL_L^M\\O[",
+ "G^LFL[ RMGMZ RIFNFN[ RNQOOPNRMUMWNXOYRY[ RWOXRXZ RUMVNWQW[ RI[Q[ RT[\\[ RJFLG RKFLH RLZJ[ RLYK[ RNYO[ RNZP[ RWZU[ RWYV[ RYYZ[ RYZ[[",
+ "LXQFQHSHSFQF RRFRH RQGSG RQMQ[ RRNRZ RNMSMS[ RN[V[ ROMQN RPMQO RQZO[ RQYP[ RSYT[ RSZU[",
+ "KXRFRHTHTFRF RSFSH RRGTG RRMR^QaPb RSNS]R` ROMTMT]S`RaPbMbLaL_N_NaMaM` RPMRN RQMRO",
+ "G]LFL[ RMGMZ RIFNFN[ RWNNW RRSY[ RRTX[ RQTW[ RTM[M RI[Q[ RT[[[ RJFLG RKFLH RUMWN RZMWN RLZJ[ RLYK[ RNYO[ RNZP[ RWYU[ RVYZ[",
+ "LXQFQ[ RRGRZ RNFSFS[ RN[V[ ROFQG RPFQH RQZO[ RQYP[ RSYT[ RSZU[",
+ "AcFMF[ RGNGZ RCMHMH[ RHQIOJNLMOMQNROSRS[ RQORRRZ ROMPNQQQ[ RSQTOUNWMZM\\N]O^R^[ R\\O]R]Z RZM[N\\Q\\[ RC[K[ RN[V[ RY[a[ RDMFN REMFO RFZD[ RFYE[ RHYI[ RHZJ[ RQZO[ RQYP[ RSYT[ RSZU[ R\\ZZ[ R\\Y[[ R^Y_[ R^Z`[",
+ "G^LML[ RMNMZ RIMNMN[ RNQOOPNRMUMWNXOYRY[ RWOXRXZ RUMVNWQW[ RI[Q[ RT[\\[ RJMLN RKMLO RLZJ[ RLYK[ RNYO[ RNZP[ RWZU[ RWYV[ RYYZ[ RYZ[[",
+ "H\\QMNNLPKSKULXNZQ[S[VZXXYUYSXPVNSMQM RMPLRLVMX RWXXVXRWP RQMONNOMRMVNYOZQ[ RS[UZVYWVWRVOUNSM",
+ "G\\LMLb RMNMa RIMNMNb RNPONQMSMVNXPYSYUXXVZS[Q[OZNX RWPXRXVWX RSMUNVOWRWVVYUZS[ RIbQb RJMLN RKMLO RLaJb RL`Kb RN`Ob RNaPb",
+ "H\\VNVb RWOWa RUNWNXMXb RVPUNSMQMNNLPKSKULXNZQ[S[UZVX RMPLRLVMX RQMONNOMRMVNYOZQ[ RSb[b RVaTb RV`Ub RX`Yb RXaZb",
+ "IZNMN[ RONOZ RKMPMP[ RWOWNVNVPXPXNWMUMSNQPPS RK[S[ RLMNN RMMNO RNZL[ RNYM[ RPYQ[ RPZR[",
+ "J[WOXMXQWOVNTMPMNNMOMQNSPTUUWVXY RNNMQ RNRPSUTWU RXVWZ RMONQPRUSWTXVXYWZU[Q[OZNYMWM[NY",
+ "KZPHPVQYRZT[V[XZYX RQHQWRY RPHRFRWSZT[ RMMVM",
+ "G^LMLVMYNZP[S[UZVYWW RMNMWNY RIMNMNWOZP[ RWMW[\\[ RXNXZ RTMYMY[ RJMLN RKMLO RYYZ[ RYZ[[",
+ "I[LMR[ RMMRY RNMSY RXNSYR[ RJMQM RTMZM RKMNO RPMNN RVMXN RYMXN",
+ "F^JMN[ RKMNX RLMOX RRMOXN[ RRMV[ RSMVX RRMTMWX RZNWXV[ RGMOM RWM]M RHMKN RNMLN RXMZN R\\MZN",
+ "H\\LMV[ RMMW[ RNMX[ RWNMZ RJMQM RTMZM RJ[P[ RS[Z[ RKMMN RPMNN RUMWN RYMWN RMZK[ RMZO[ RVZT[ RWZY[",
+ "H[LMR[ RMMRY RNMSY RXNSYP_NaLbJbIaI_K_KaJaJ` RJMQM RTMZM RKMNO RPMNN RVMXN RYMXN",
+ "I[VML[ RWMM[ RXMN[ RXMLMLQ RL[X[XW RMMLQ RNMLP ROMLO RQMLN RS[XZ RU[XY RV[XX RW[XW",
+ "KYTBRCQDPFPHQJRKSMSOQQ RRCQEQGRISJTLTNSPORSTTVTXSZR[Q]Q_Ra RQSSUSWRYQZP\\P^Q`RaTb",
+ "NVRBRb",
+ "KYPBRCSDTFTHSJRKQMQOSQ RRCSESGRIQJPLPNQPURQTPVPXQZR[S]S_Ra RSSQUQWRYSZT\\T^S`RaPb",
+ "F^IUISJPLONOPPTSVTXTZS[Q RISJQLPNPPQTTVUXUZT[Q[O",
+ "JZJFJ[K[KFLFL[M[MFNFN[O[OFPFP[Q[QFRFR[S[SFTFT[U[UFVFV[W[WFXFX[Y[YFZFZ["
+ }
+},
+{
+ "Futura Light",
+ 0.041, /* X scale */
+ 0.041, /* Y scale */
+ 0.95, /* X spacing extra scale */
+ 0.08, /* Line width scale */
+ 0.9, /* horizontal offset */
+ 10.5, /* vertical offset */
+ {
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "MWRFRT RRYQZR[SZRY",
+ "JZNFNM RVFVM",
+ "H]SBLb RYBRb RLOZO RKUYU",
+ "H\\PBP_ RTBT_ RYIWGTFPFMGKIKKLMMNOOUQWRXSYUYXWZT[P[MZKX",
+ "F^[FI[ RNFPHPJOLMMKMIKIIJGLFNFPGSHVHYG[F RWTUUTWTYV[X[ZZ[X[VYTWT",
+ "E_\\O\\N[MZMYNXPVUTXRZP[L[JZIYHWHUISJRQNRMSKSIRGPFNGMIMKNNPQUXWZY[[[\\Z\\Y",
+ "MWRHQGRFSGSIRKQL",
+ "KYVBTDRGPKOPOTPYR]T`Vb",
+ "KYNBPDRGTKUPUTTYR]P`Nb",
+ "JZRLRX RMOWU RWOMU",
+ "E_RIR[ RIR[R",
+ "NVSWRXQWRVSWSYQ[",
+ "E_IR[R",
+ "NVRVQWRXSWRV",
+ "G][BIb",
+ "H\\QFNGLJKOKRLWNZQ[S[VZXWYRYOXJVGSFQF",
+ "H\\NJPISFS[",
+ "H\\LKLJMHNGPFTFVGWHXJXLWNUQK[Y[",
+ "H\\MFXFRNUNWOXPYSYUXXVZS[P[MZLYKW",
+ "H\\UFKTZT RUFU[",
+ "H\\WFMFLOMNPMSMVNXPYSYUXXVZS[P[MZLYKW",
+ "H\\XIWGTFRFOGMJLOLTMXOZR[S[VZXXYUYTXQVOSNRNOOMQLT",
+ "H\\YFO[ RKFYF",
+ "H\\PFMGLILKMMONSOVPXRYTYWXYWZT[P[MZLYKWKTLRNPQOUNWMXKXIWGTFPF",
+ "H\\XMWPURRSQSNRLPKMKLLINGQFRFUGWIXMXRWWUZR[P[MZLX",
+ "NVROQPRQSPRO RRVQWRXSWRV",
+ "NVROQPRQSPRO RSWRXQWRVSWSYQ[",
+ "F^ZIJRZ[",
+ "E_IO[O RIU[U",
+ "F^JIZRJ[",
+ "I[LKLJMHNGPFTFVGWHXJXLWNVORQRT RRYQZR[SZRY",
+ "E`WNVLTKQKOLNMMPMSNUPVSVUUVS RQKOMNPNSOUPV RWKVSVUXVZV\\T]Q]O\\L[JYHWGTFQFNGLHJJILHOHRIUJWLYNZQ[T[WZYYZX RXKWSWUXV",
+ "I[RFJ[ RRFZ[ RMTWT",
+ "G\\KFK[ RKFTFWGXHYJYLXNWOTP RKPTPWQXRYTYWXYWZT[K[",
+ "H]ZKYIWGUFQFOGMILKKNKSLVMXOZQ[U[WZYXZV",
+ "G\\KFK[ RKFRFUGWIXKYNYSXVWXUZR[K[",
+ "H[LFL[ RLFYF RLPTP RL[Y[",
+ "HZLFL[ RLFYF RLPTP",
+ "H]ZKYIWGUFQFOGMILKKNKSLVMXOZQ[U[WZYXZVZS RUSZS",
+ "G]KFK[ RYFY[ RKPYP",
+ "NVRFR[",
+ "JZVFVVUYTZR[P[NZMYLVLT",
+ "G\\KFK[ RYFKT RPOY[",
+ "HYLFL[ RL[X[",
+ "F^JFJ[ RJFR[ RZFR[ RZFZ[",
+ "G]KFK[ RKFY[ RYFY[",
+ "G]PFNGLIKKJNJSKVLXNZP[T[VZXXYVZSZNYKXIVGTFPF",
+ "G\\KFK[ RKFTFWGXHYJYMXOWPTQKQ",
+ "G]PFNGLIKKJNJSKVLXNZP[T[VZXXYVZSZNYKXIVGTFPF RSWY]",
+ "G\\KFK[ RKFTFWGXHYJYLXNWOTPKP RRPY[",
+ "H\\YIWGTFPFMGKIKKLMMNOOUQWRXSYUYXWZT[P[MZKX",
+ "JZRFR[ RKFYF",
+ "G]KFKULXNZQ[S[VZXXYUYF",
+ "I[JFR[ RZFR[",
+ "F^HFM[ RRFM[ RRFW[ R\\FW[",
+ "H\\KFY[ RYFK[",
+ "I[JFRPR[ RZFRP",
+ "H\\YFK[ RKFYF RK[Y[",
+ "KYOBOb RPBPb ROBVB RObVb",
+ "KYKFY^",
+ "KYTBTb RUBUb RNBUB RNbUb",
+ "JZRDJR RRDZR",
+ "I[Ib[b",
+ "NVSKQMQORPSORNQO",
+ "I\\XMX[ RXPVNTMQMONMPLSLUMXOZQ[T[VZXX",
+ "H[LFL[ RLPNNPMSMUNWPXSXUWXUZS[P[NZLX",
+ "I[XPVNTMQMONMPLSLUMXOZQ[T[VZXX",
+ "I\\XFX[ RXPVNTMQMONMPLSLUMXOZQ[T[VZXX",
+ "I[LSXSXQWOVNTMQMONMPLSLUMXOZQ[T[VZXX",
+ "MYWFUFSGRJR[ ROMVM",
+ "I\\XMX]W`VaTbQbOa RXPVNTMQMONMPLSLUMXOZQ[T[VZXX",
+ "I\\MFM[ RMQPNRMUMWNXQX[",
+ "NVQFRGSFREQF RRMR[",
+ "MWRFSGTFSERF RSMS^RaPbNb",
+ "IZMFM[ RWMMW RQSX[",
+ "NVRFR[",
+ "CaGMG[ RGQJNLMOMQNRQR[ RRQUNWMZM\\N]Q][",
+ "I\\MMM[ RMQPNRMUMWNXQX[",
+ "I\\QMONMPLSLUMXOZQ[T[VZXXYUYSXPVNTMQM",
+ "H[LMLb RLPNNPMSMUNWPXSXUWXUZS[P[NZLX",
+ "I\\XMXb RXPVNTMQMONMPLSLUMXOZQ[T[VZXX",
+ "KXOMO[ ROSPPRNTMWM",
+ "J[XPWNTMQMNNMPNRPSUTWUXWXXWZT[Q[NZMX",
+ "MYRFRWSZU[W[ ROMVM",
+ "I\\MMMWNZP[S[UZXW RXMX[",
+ "JZLMR[ RXMR[",
+ "G]JMN[ RRMN[ RRMV[ RZMV[",
+ "J[MMX[ RXMM[",
+ "JZLMR[ RXMR[P_NaLbKb",
+ "J[XMM[ RMMXM RM[X[",
+ "KYTBRCQDPFPHQJRKSMSOQQ RRCQEQGRISJTLTNSPORSTTVTXSZR[Q]Q_Ra RQSSUSWRYQZP\\P^Q`RaTb",
+ "NVRBRb",
+ "KYPBRCSDTFTHSJRKQMQOSQ RRCSESGRIQJPLPNQPURQTPVPXQZR[S]S_Ra RSSQUQWRYSZT\\T^S`RaPb",
+ "F^IUISJPLONOPPTSVTXTZS[Q RISJQLPNPPQTTVUXUZT[Q[O",
+ "JZJFJ[K[KFLFL[M[MFNFN[O[OFPFP[Q[QFRFR[S[SFTFT[U[UFVFV[W[WFXFX[Y[YFZFZ[",
+ }
+},
+{
+ "Futura Medium",
+ 0.041, /* X scale */
+ 0.041, /* Y scale */
+ 0.95, /* X spacing extra scale */
+ 0.065, /* Line width scale */
+ 0.1, /* horizontal offset */
+ 10.5, /* vertical offset */
+ {
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "JZ",
+ "MXRFRTST RRFSFST RRXQYQZR[S[TZTYSXRX RRYRZSZSYRY",
+ "I[NFMGMM RNGMM RNFOGMM RWFVGVM RWGVM RWFXGVM",
+ "H]SBLb RYBRb RLOZO RKUYU",
+ "I\\RBR_S_ RRBSBS_ RWIYIWGTFQFNGLILKMMNNVRWSXUXWWYTZQZOYNX RWIVHTGQGNHMIMKNMVQXSYUYWXYWZT[Q[NZLXNX RXXUZ",
+ "F^[FI[ RNFPHPJOLMMKMIKIIJGLFNFPGSHVHYG[F RWTUUTWTYV[X[ZZ[X[VYTWT",
+ "F_[NZO[P\\O\\N[MZMYNXPVUTXRZP[M[JZIXIUJSPORMSKSIRGPFNGMIMKNNPQUXWZZ[[[\\Z\\Y RM[KZJXJUKSMQ RMKNMVXXZZ[",
+ "NWSFRGRM RSGRM RSFTGRM",
+ "KYVBTDRGPKOPOTPYR]T`Vb RTDRHQKPPPTQYR\\T`",
+ "KYNBPDRGTKUPUTTYR]P`Nb RPDRHSKTPTTSYR\\P`",
+ "JZRFQGSQRR RRFRR RRFSGQQRR RMINIVOWO RMIWO RMIMJWNWO RWIVINOMO RWIMO RWIWJMNMO",
+ "F_RIRZSZ RRISISZ RJQ[Q[R RJQJR[R",
+ "MXTZS[R[QZQYRXSXTYT\\S^Q_ RRYRZSZSYRY RS[T\\ RTZS^",
+ "E_IR[R",
+ "MXRXQYQZR[S[TZTYSXRX RRYRZSZSYRY",
+ "G^[BIbJb R[B\\BJb",
+ "H\\QFNGLJKOKRLWNZQ[S[VZXWYRYOXJVGSFQF ROGMJLOLRMWOZ RNYQZSZVY RUZWWXRXOWJUG RVHSGQGNH",
+ "H\\NJPISFS[ RNJNKPJRHR[S[",
+ "H\\LKLJMHNGPFTFVGWHXJXLWNUQL[ RLKMKMJNHPGTGVHWJWLVNTQK[ RLZYZY[ RK[Y[",
+ "H\\MFXFQO RMFMGWG RWFPO RQNSNVOXQYTYUXXVZS[P[MZLYKWLW RPOSOVPXS RTOWQXTXUWXTZ RXVVYSZPZMYLW ROZLX",
+ "H\\UIU[V[ RVFV[ RVFKVZV RUILV RLUZUZV",
+ "H\\MFLO RNGMN RMFWFWG RNGWG RMNPMSMVNXPYSYUXXVZS[P[MZLYKWLW RLOMOONSNVOXR RTNWPXSXUWXTZ RXVVYSZPZMYLW ROZLX",
+ "H\\VGWIXIWGTFRFOGMJLOLTMXOZR[S[VZXXYUYTXQVOSNRNOOMQ RWHTGRGOH RPGNJMOMTNXQZ RMVOYRZSZVYXV RTZWXXUXTWQTO RXSVPSOROOPMS RQONQMT",
+ "H\\KFYFO[ RKFKGXG RXFN[O[",
+ "H\\PFMGLILKMMNNPOTPVQWRXTXWWYTZPZMYLWLTMRNQPPTOVNWMXKXIWGTFPF RNGMIMKNMPNTOVPXRYTYWXYWZT[P[MZLYKWKTLRNPPOTNVMWKWIVG RWHTGPGMH RLXOZ RUZXX",
+ "H\\WPURRSQSNRLPKMKLLINGQFRFUGWIXMXRWWUZR[P[MZLXMXNZ RWMVPSR RWNUQRRQRNQLN RPRMPLMLLMIPG RLKNHQGRGUHWK RSGVIWMWRVWTZ RUYRZPZMY",
+ "MXRMQNQORPSPTOTNSMRM RRNROSOSNRN RRXQYQZR[S[TZTYSXRX RRYRZSZSYRY",
+ "MXRMQNQORPSPTOTNSMRM RRNROSOSNRN RTZS[R[QZQYRXSXTYT\\S^Q_ RRYRZSZSYRY RS[T\\ RTZS^",
+ "F^ZIJRZ[",
+ "F_JM[M[N RJMJN[N RJU[U[V RJUJV[V",
+ "F^JIZRJ[",
+ "I\\LKLJMHNGQFTFWGXHYJYLXNWOUPRQ RLKMKMJNHQGTGWHXJXLWNUORP RMIPG RUGXI RXMTP RRPRTSTSP RRXQYQZR[S[TZTYSXRX RRYRZSZSYRY",
+ "E`WNVLTKQKOLNMMPMSNUPVSVUUVS RQKOMNPNSOUPV RWKVSVUXVZV\\T]Q]O\\L[JYHWGTFQFNGLHJJILHOHRIUJWLYNZQ[T[WZYYZX RXKWSWUXV",
+ "H\\RFJ[ RRIK[J[ RRIY[Z[ RRFZ[ RMUWU RLVXV",
+ "H\\LFL[ RMGMZ RLFTFWGXHYJYMXOWPTQ RMGTGWHXJXMWOTP RMPTPWQXRYTYWXYWZT[L[ RMQTQWRXTXWWYTZMZ",
+ "H]ZKYIWGUFQFOGMILKKNKSLVMXOZQ[U[WZYXZV RZKYKXIWHUGQGOHMKLNLSMVOYQZUZWYXXYVZV",
+ "H]LFL[ RMGMZ RLFSFVGXIYKZNZSYVXXVZS[L[ RMGSGVHWIXKYNYSXVWXVYSZMZ",
+ "I\\MFM[ RNGNZ RMFYF RNGYGYF RNPTPTQ RNQTQ RNZYZY[ RM[Y[",
+ "I[MFM[ RNGN[M[ RMFYF RNGYGYF RNPTPTQ RNQTQ",
+ "H]ZKYIWGUFQFOGMILKKNKSLVMXOZQ[U[WZYXZVZRUR RZKYKXIWHUGQGOHNIMKLNLSMVNXOYQZUZWYXXYVYSUSUR",
+ "G]KFK[ RKFLFL[K[ RYFXFX[Y[ RYFY[ RLPXP RLQXQ",
+ "NWRFR[S[ RRFSFS[",
+ "J[VFVVUYSZQZOYNVMV RVFWFWVVYUZS[Q[OZNYMV",
+ "H]LFL[M[ RLFMFM[ RZFYFMR RZFMS RPOY[Z[ RQOZ[",
+ "IZMFM[ RMFNFNZ RNZYZY[ RM[Y[",
+ "F^JFJ[ RKKK[J[ RKKR[ RJFRX RZFRX RYKR[ RYKY[Z[ RZFZ[",
+ "G]KFK[ RLIL[K[ RLIY[ RKFXX RXFXX RXFYFY[",
+ "G]PFNGLIKKJNJSKVLXNZP[T[VZXXYVZSZNYKXIVGTFPF RQGNHLKKNKSLVNYQZSZVYXVYSYNXKVHSGQG",
+ "H\\LFL[ RMGM[L[ RLFUFWGXHYJYMXOWPUQMQ RMGUGWHXJXMWOUPMP",
+ "G]PFNGLIKKJNJSKVLXNZP[T[VZXXYVZSZNYKXIVGTFPF RQGNHLKKNKSLVNYQZSZVYXVYSYNXKVHSGQG RSXX]Y] RSXTXY]",
+ "H\\LFL[ RMGM[L[ RLFTFWGXHYJYMXOWPTQMQ RMGTGWHXJXMWOTPMP RRQX[Y[ RSQY[",
+ "H\\YIWGTFPFMGKIKKLMMNOOTQVRWSXUXXWYTZPZNYMXKX RYIWIVHTGPGMHLILKMMONTPVQXSYUYXWZT[P[MZKX",
+ "J[RGR[ RSGS[R[ RLFYFYG RLFLGYG",
+ "G]KFKULXNZQ[S[VZXXYUYF RKFLFLUMXNYQZSZVYWXXUXFYF",
+ "H\\JFR[ RJFKFRX RZFYFRX RZFR[",
+ "E_GFM[ RGFHFMX RRFMX RRIM[ RRIW[ RRFWX R]F\\FWX R]FW[",
+ "H\\KFX[Y[ RKFLFY[ RYFXFK[ RYFL[K[",
+ "I\\KFRPR[S[ RKFLFSP RZFYFRP RZFSPS[",
+ "H\\XFK[ RYFL[ RKFYF RKFKGXG RLZYZY[ RK[Y[",
+ "KYOBOb RPBPb ROBVB RObVb",
+ "KYKFY^",
+ "KYTBTb RUBUb RNBUB RNbUb",
+ "G]JTROZT RJTRPZT",
+ "H\\Hb\\b",
+ "LXPFUL RPFOGUL",
+ "H\\WMW[X[ RWMXMX[ RWPUNSMPMNNLPKSKULXNZP[S[UZWX RWPSNPNNOMPLSLUMXNYPZSZWX",
+ "H\\LFL[M[ RLFMFM[ RMPONQMTMVNXPYSYUXXVZT[Q[OZMX RMPQNTNVOWPXSXUWXVYTZQZMX",
+ "I[XPVNTMQMONMPLSLUMXOZQ[T[VZXX RXPWQVOTNQNOONPMSMUNXOYQZTZVYWWXX",
+ "H\\WFW[X[ RWFXFX[ RWPUNSMPMNNLPKSKULXNZP[S[UZWX RWPSNPNNOMPLSLUMXNYPZSZWX",
+ "I[MTXTXQWOVNTMQMONMPLSLUMXOZQ[T[VZXX RMSWSWQVOTNQNOONPMSMUNXOYQZTZVYWWXX",
+ "LZWFUFSGRJR[S[ RWFWGUGSH RTGSJS[ ROMVMVN ROMONVN",
+ "H\\XMWMW\\V_U`SaQaO`N_L_ RXMX\\W_UaSbPbNaL_ RWPUNSMPMNNLPKSKULXNZP[S[UZWX RWPSNPNNOMPLSLUMXNYPZSZWX",
+ "H\\LFL[M[ RLFMFM[ RMQPNRMUMWNXQX[ RMQPORNTNVOWQW[X[",
+ "NWRFQGQHRISITHTGSFRF RRGRHSHSGRG RRMR[S[ RRMSMS[",
+ "NWRFQGQHRISITHTGSFRF RRGRHSHSGRG RRMRbSb RRMSMSb",
+ "H[LFL[M[ RLFMFM[ RXMWMMW RXMMX RPTV[X[ RQSX[",
+ "NWRFR[S[ RRFSFS[",
+ "CbGMG[H[ RGMHMH[ RHQKNMMPMRNSQS[ RHQKOMNONQORQR[S[ RSQVNXM[M]N^Q^[ RSQVOXNZN\\O]Q][^[",
+ "H\\LML[M[ RLMMMM[ RMQPNRMUMWNXQX[ RMQPORNTNVOWQW[X[",
+ "I\\QMONMPLSLUMXOZQ[T[VZXXYUYSXPVNTMQM RQNOONPMSMUNXOYQZTZVYWXXUXSWPVOTNQN",
+ "H\\LMLbMb RLMMMMb RMPONQMTMVNXPYSYUXXVZT[Q[OZMX RMPQNTNVOWPXSXUWXVYTZQZMX",
+ "H\\WMWbXb RWMXMXb RWPUNSMPMNNLPKSKULXNZP[S[UZWX RWPSNPNNOMPLSLUMXNYPZSZWX",
+ "KYOMO[P[ ROMPMP[ RPSQPSNUMXM RPSQQSOUNXNXM",
+ "J[XPWNTMQMNNMPNRPSUUWV RVUWWWXVZ RWYTZQZNY ROZNXMX RXPWPVN RWOTNQNNO RONNPOR RNQPRUTWUXWXXWZT[Q[NZMX",
+ "MXRFR[S[ RRFSFS[ ROMVMVN ROMONVN",
+ "H\\LMLWMZO[R[TZWW RLMMMMWNYPZRZTYWW RWMW[X[ RWMXMX[",
+ "JZLMR[ RLMMMRY RXMWMRY RXMR[",
+ "F^IMN[ RIMJMNX RRMNX RRPN[ RRPV[ RRMVX R[MZMVX R[MV[",
+ "I[LMW[X[ RLMMMX[ RXMWML[ RXMM[L[",
+ "JZLMR[ RLMMMRY RXMWMRYNb RXMR[ObNb",
+ "I[VNL[ RXMNZ RLMXM RLMLNVN RNZXZX[ RL[X[",
+ "KYUBNRUb",
+ "NVRBRb",
+ "KYOBVROb",
+ "F^IUISJPLONOPPTSVTXTZS[Q RISJQLPNPPQTTVUXUZT[Q[O",
+ "JZJFJ[K[KFLFL[M[MFNFN[O[OFPFP[Q[QFRFR[S[SFTFT[U[UFVFV[W[WFXFX[Y[YFZFZ[",
+ }
+}
+};
+
+
diff --git a/render/render.h b/render/render.h
new file mode 100644
index 0000000..e7bcdee
--- /dev/null
+++ b/render/render.h
@@ -0,0 +1,239 @@
+
+#ifndef RENDER2D_H
+#define RENDER2D_H
+
+/*
+ * render2d
+ *
+ * Simple 2D raster rendering support.
+ *
+ * Author: Graeme W. Gill
+ * Date: 28/12/2005
+ *
+ * Copyright 2005, 2008, 2012 Graeme W. Gill
+ * All rights reserved.
+ *
+ * This material is licenced under the GNU AFFERO GENERAL PUBLIC LICENSE Version 3 :-
+ * see the License.txt file for licencing details.
+ */
+
+/* This is basically a simple 2D ray tracing renderer, so it's not especially */
+/* efficient, but it's simple and direct, easy to add new primitives or */
+/* capabilities, is high quality, and has an accelleration algorithm that */
+/* makes it fast enough for printed output. */
+
+/* Mathematical coordinate in mm are used for primitives, ie. the origin is */
+/* the bottom left corner. */
+/* Device color values range from 0.0 to 1.0 */
+
+#define MXCH2D 8 /* Maximum color channels */
+#define TOTC2D (MXCH2D+1) /* Maximum total components */
+#define PRIX2D (MXCH2D) /* Index of primitive */
+
+/* Color type */
+/* Shouldn't this be an xcolorants mask ? */
+typedef enum {
+ w_2d, /* Video style grey */
+ k_2d, /* Printing style grey */
+ lab_2d, /* Lab */
+ rgb_2d, /* RGB */
+ cmyk_2d, /* CMYK */
+ ncol_2d, /* N color */
+ ncol_a_2d /* N color with extra as alpha */
+} colort2d;
+
+/* Pixel depth */
+typedef enum {
+ bpc8_2d, /* 8 bits per component */
+ bpc16_2d /* 16 bits per component */
+} depth2d;
+
+typedef double color2d[TOTC2D];
+
+/* Font type */
+typedef enum {
+ rowman_s = 0, /* Rownman, single stroke */
+ rowman_d = 1, /* Rownman, double stroke */
+ rowman_t = 2, /* Rownman, triple stroke */
+ timesr = 3, /* Times Roman */
+ timesr_b = 4, /* Times Roman, Bold */
+ futura_l = 5, /* Futura, Light */
+ futura_m = 6 /* Futura, Medium */
+} font2d;
+
+/* ------------------------------------ */
+
+struct _render2d;
+
+#define PRIM_STRUCT \
+/* primt2d tag; */ /* Type of primitive */ \
+ int ix; /* Index (order added) */ \
+ int ncc; /* Number of color components */ \
+ struct _prim2d *next; /* Linked list to next primitive */ \
+ struct _prim2d *yl0; /* Previous lines Y list linked list */ \
+ struct _prim2d *yl; /* Active Y list linked list */ \
+ struct _prim2d *xl; /* Active X list linked list */ \
+ double x0, y0, x1, y1; /* Extent, top & left inclusive, bot & right non-inclusive */ \
+ void (*del)(struct _prim2d *s); /* Delete the object */ \
+ /* Render the object at location. Return nz if in primitive */ \
+ int (*rend)(struct _prim2d *s, color2d rv, double x, double y);
+
+struct _prim2d {
+ PRIM_STRUCT
+}; typedef struct _prim2d prim2d;
+
+/* ------------------------------------ */
+/* Solid rectange primitive */
+struct _rect2d {
+ PRIM_STRUCT
+ double rx0, ry0, rx1, ry1; /* Rectangle verticies */
+ color2d c; /* Color of rectangle */
+}; typedef struct _rect2d rect2d;
+
+prim2d *new_rect2d(struct _render2d *s, double x, double y, double w, double h, color2d c);
+
+/* ------------------------------------ */
+/* Vertex shaded rectange */
+struct _rectvs2d {
+ PRIM_STRUCT
+ double rx0, ry0, rx1, ry1; /* Rectangle verticies */
+ color2d c[4]; /* Bot left, bot right, top left, top right */
+ int x_blend; /* Blending rule flags, 0 = linear, 1 = spline, 2 = sine */
+ int y_blend;
+ int y_sine;
+}; typedef struct _rectvs2d rectvs2d;
+
+prim2d *new_rectvs2d(struct _render2d *s, double x, double y, double w, double h, color2d c[4]);
+
+/* ------------------------------------ */
+/* Vertex shaded triangle */
+struct _trivs2d {
+ PRIM_STRUCT
+ double be[3][3]; /* baricentric equations */
+ color2d c[3]; /* Color of each vertex */
+}; typedef struct _trivs2d trivs2d;
+
+prim2d *new_trivs2d(struct _render2d *s, double v[3][2], color2d c[3]);
+
+/* ------------------------------------ */
+/* A single line. */
+
+struct _line2d {
+ PRIM_STRUCT
+ double lx0, ly0, lx1, ly1; /* Line verticies */
+ double ww; /* half width of line squared */
+ int cap; /* 0 = butt, 1 = round, 2 = square */
+ color2d c; /* Color of the line */
+ int t; /* nz if line is degenerate */
+ double vx, vy; /* Vector relative to x0 y0 */
+}; typedef struct _line2d line2d;
+
+prim2d *new_line2d(struct _render2d *s, double x0, double y0, double x1, double y1, double w, int cap, color2d c);
+
+/* ------------------------------------ */
+
+/* add a dashed line */
+void add_dashed_line2d(
+struct _render2d *s,
+double x0, double y0,
+double x1, double y1,
+double w,
+double on, double off,
+int cap,
+color2d c);
+
+/* Add a text character at the given location using lines */
+void add_char2d(
+struct _render2d *s,
+double *xinc, /* Add increment to next character */
+double *yinc,
+font2d fo, /* Font to use */
+char ch, /* Character code to be printed */
+double x, double y, /* Location of bottom left of normal orientation text */
+double h, /* Height of text in normal orientation */
+int or, /* Orintation, 0 = right, 1 = down, 2 = left, 3 = up */
+color2d c /* Color of text */
+);
+
+/* Add a string from the given location using lines. */
+void add_string2d(
+struct _render2d *s,
+double *xinc, /* Add increment to next character */
+double *yinc,
+font2d fo, /* Font to use */
+char *string, /* Character code to be printed */
+double x, double y, /* Location of bottom left of normal orientation text */
+double h, /* Height of text in normal orientation */
+int or, /* Orintation, 0 = right, 1 = down, 2 = left, 3 = up */
+color2d c /* Color of text */
+);
+
+/* Return the total width of the string without adding it */
+void meas_string2d(
+struct _render2d *s,
+double *xinc, /* Add increment to next character */
+double *yinc,
+font2d fo, /* Font to use */
+char *string, /* Character code to be printed */
+double h, /* Height of text in normal orientation */
+int or /* Orintation, 0 = right, 1 = down, 2 = left, 3 = up */
+);
+
+/* ------------------------------------ */
+/* Render object */
+
+struct _render2d {
+
+/* Private: */
+ int ix; /* Next primitive index */
+ double fw, fh; /* Page size in mm including margines */
+ double lm, rm, tm, bm; /* Page margines in mm */
+ double w, h; /* Page size in mm excluding margines */
+ double hres, vres; /* Page pixel resolution in pixels/mm */
+ int pw, ph; /* Page size in pixels */
+ colort2d csp; /* Color space */
+ int ncc; /* Number of color components */
+ depth2d dpth; /* Depth of the components */
+ int dither; /* Dither flag */
+
+ color2d defc; /* Default color value */
+
+ void (*bgfunc)(void *cntx, color2d c, double x, double y); /* BG color function */
+ void *cntx;
+
+ prim2d *head; /* Start of list of primitives in rendering order */
+ prim2d *yl; /* Active Y list linked list head */
+ prim2d *xl; /* Active X list linked list head */
+
+/* Public: */
+ /* Methods */
+ void (*del)(struct _render2d *s); /* Free ourselves and all primitives */
+
+ void (*set_defc)(struct _render2d *s, color2d c); /* Set the default/background color */
+
+ void (*set_bg_func)(struct _render2d *s, /* Set background color function */
+ void (*func)(void *cntx, color2d c, double x, double y), /* Func can choose not to set */
+ void *cntx
+ );
+
+ void (*add)(struct _render2d *s, prim2d *p); /* Add a primitive */
+
+ int (*write)(struct _render2d *s, char *filename, int comprn);
+ /* Render and write to a TIFF file */
+}; typedef struct _render2d render2d;
+
+/* Constructor */
+render2d *new_render2d(
+ double w, /* width in mm */
+ double h, /* height in mm */
+ double ma[4], /* Margines, left, right, top, bottom, NULL for zero in mm */
+ double hres, /* horizontal resolution in pixels/mm */
+ double vres, /* horizontal resolution in pixels/mm */
+ colort2d csp, /* Color type */
+ int nd, /* Number of channels if c = ncol */
+ depth2d dpth, /* Pixel depth */
+ int dither /* Dither flag */
+);
+
+#endif /* RENDER2D_H */
+
diff --git a/render/screens.h b/render/screens.h
new file mode 100644
index 0000000..353597b
--- /dev/null
+++ b/render/screens.h
@@ -0,0 +1,811 @@
+
+/* screens.h is output from makescreen */
+/* (Simplified from DPS code) */
+
+/*
+ * Copyright 2005, 2012 Graeme W. Gill
+ * All rights reserved.
+ * This material is licenced under the GNU AFFERO GENERAL PUBLIC LICENSE Version 3 :-
+ * see the License.txt file for licencing details.
+ */
+
+static ccoord screen0_0[6241] = {
+ { 31, 36 },{ 70, 70 },{ 73, 27 },{ 28, 72 },{ 48, 13 },{ 8, 47 },{ 50, 52 },{ 14, 13 },
+ { 62, 40 },{ 14, 64 },{ 55, 3 },{ 25, 24 },{ 37, 58 },{ 78, 2 },{ 56, 27 },{ 69, 57 },
+ { 37, 1 },{ 11, 31 },{ 26, 48 },{ 67, 17 },{ 43, 33 },{ 9, 76 },{ 47, 65 },{ 77, 48 },
+ { 30, 14 },{ 61, 64 },{ 1, 14 },{ 17, 57 },{ 49, 40 },{ 18, 1 },{ 5, 36 },{ 50, 75 },
+ { 42, 17 },{ 0, 61 },{ 65, 9 },{ 19, 40 },{ 39, 47 },{ 67, 36 },{ 22, 8 },{ 8, 20 },
+ { 60, 50 },{ 36, 25 },{ 36, 68 },{ 61, 73 },{ 28, 60 },{ 59, 19 },{ 1, 67 },{ 20, 32 },
+ { 75, 42 },{ 32, 7 },{ 74, 7 },{ 53, 33 },{ 7, 55 },{ 56, 59 },{ 44, 4 },{ 7, 6 },
+ { 37, 40 },{ 3, 28 },{ 17, 70 },{ 20, 51 },{ 47, 26 },{ 19, 19 },{ 43, 53 },{ 71, 0 },
+ { 65, 26 },{ 42, 73 },{ 73, 54 },{ 56, 9 },{ 23, 63 },{ 31, 29 },{ 11, 42 },{ 58, 43 },
+ { 54, 68 },{ 0, 19 },{ 25, 77 },{ 34, 51 },{ 5, 70 },{ 39, 14 },{ 67, 46 },{ 51, 19 },
+ { 18, 24 },{ 66, 78 },{ 75, 32 },{ 46, 60 },{ 26, 40 },{ 67, 64 },{ 28, 4 },{ 9, 62 },
+ { 14, 6 },{ 43, 44 },{ 71, 11 },{ 2, 52 },{ 31, 19 },{ 32, 67 },{ 60, 35 },{ 58, 78 },
+ { 11, 23 },{ 3, 75 },{ 18, 45 },{ 53, 49 },{ 46, 7 },{ 39, 30 },{ 69, 20 },{ 78, 35 },
+ { 31, 56 },{ 5, 12 },{ 73, 63 },{ 31, 77 },{ 62, 56 },{ 24, 16 },{ 13, 54 },{ 60, 13 },
+ { 30, 43 },{ 49, 70 },{ 14, 73 },{ 14, 33 },{ 62, 30 },{ 40, 63 },{ 41, 22 },{ 2, 41 },
+ { 46, 37 },{ 72, 72 },{ 39, 5 },{ 74, 22 },{ 66, 52 },{ 27, 34 },{ 22, 73 },{ 3, 4 },
+ { 52, 6 },{ 50, 58 },{ 51, 29 },{ 23, 59 },{ 10, 10 },{ 73, 46 },{ 63, 70 },{ 10, 37 },
+ { 38, 75 },{ 55, 21 },{ 18, 13 },{ 62, 5 },{ 25, 54 },{ 54, 44 },{ 9, 67 },{ 35, 16 },
+ { 71, 35 },{ 7, 27 },{ 4, 57 },{ 46, 49 },{ 29, 27 },{ 77, 71 },{ 74, 13 },{ 48, 77 },
+ { 37, 36 },{ 11, 1 },{ 12, 50 },{ 58, 65 },{ 33, 47 },{ 64, 23 },{ 25, 10 },{ 41, 67 },
+ { 23, 30 },{ 46, 20 },{ 67, 42 },{ 23, 68 },{ 2, 24 },{ 5, 44 },{ 55, 54 },{ 35, 10 },
+ { 69, 3 },{ 76, 59 },{ 55, 38 },{ 52, 12 },{ 14, 21 },{ 18, 63 },{ 22, 43 },{ 41, 57 },
+ { 75, 77 },{ 69, 30 },{ 56, 71 },{ 21, 1 },{ 33, 23 },{ 34, 73 },{ 42, 41 },{ 5, 18 },
+ { 15, 47 },{ 62, 16 },{ 66, 58 },{ 31, 64 },{ 44, 30 },{ 78, 8 },{ 63, 48 },{ 18, 36 },
+ { 40, 10 },{ 44, 78 },{ 12, 58 },{ 65, 74 },{ 15, 28 },{ 53, 25 },{ 17, 5 },{ 75, 52 },
+ { 51, 64 },{ 5, 65 },{ 26, 19 },{ 1, 33 },{ 31, 53 },{ 66, 13 },{ 7, 78 },{ 71, 40 },
+ { 49, 44 },{ 35, 44 },{ 55, 76 },{ 17, 76 },{ 33, 32 },{ 32, 3 },{ 55, 14 },{ 71, 66 },
+ { 76, 24 },{ 64, 33 },{ 26, 65 },{ 10, 15 },{ 60, 59 },{ 39, 54 },{ 6, 49 },{ 13, 39 },
+ { 45, 24 },{ 61, 2 },{ 21, 13 },{ 48, 34 },{ 73, 17 },{ 12, 71 },{ 23, 48 },{ 45, 73 },
+ { 36, 61 },{ 77, 38 },{ 78, 74 },{ 20, 27 },{ 58, 52 },{ 49, 2 },{ 58, 28 },{ 78, 55 },
+ { 28, 9 },{ 36, 19 },{ 22, 36 },{ 66, 5 },{ 19, 60 },{ 48, 55 },{ 7, 30 },{ 65, 67 },
+ { 3, 9 },{ 57, 35 },{ 49, 16 },{ 26, 71 },{ 28, 50 },{ 69, 50 },{ 43, 8 },{ 6, 61 },
+ { 69, 24 },{ 21, 21 },{ 33, 41 },{ 3, 0 },{ 25, 2 },{ 52, 62 },{ 2, 46 },{ 40, 25 },
+ { 41, 70 },{ 61, 44 },{ 16, 53 },{ 73, 4 },{ 42, 49 },{ 16, 18 },{ 7, 40 },{ 59, 22 },
+ { 75, 66 },{ 58, 8 },{ 39, 38 },{ 10, 4 },{ 0, 29 },{ 40, 1 },{ 52, 46 },{ 32, 70 },
+ { 19, 68 },{ 27, 29 },{ 72, 60 },{ 43, 14 },{ 77, 14 },{ 68, 74 },{ 44, 61 },{ 16, 42 },
+ { 4, 21 },{ 68, 38 },{ 54, 73 },{ 33, 12 },{ 50, 32 },{ 18, 9 },{ 29, 57 },{ 12, 66 },
+ { 63, 62 },{ 29, 37 },{ 63, 12 },{ 71, 43 },{ 6, 73 },{ 46, 42 },{ 13, 25 },{ 51, 9 },
+ { 29, 22 },{ 10, 53 },{ 29, 77 },{ 66, 31 },{ 45, 68 },{ 22, 56 },{ 37, 32 },{ 62, 78 },
+ { 53, 56 },{ 6, 33 },{ 7, 10 },{ 49, 21 },{ 70, 53 },{ 14, 78 },{ 2, 64 },{ 24, 45 },
+ { 65, 19 },{ 34, 63 },{ 58, 47 },{ 35, 78 },{ 71, 6 },{ 38, 51 },{ 0, 50 },{ 11, 17 },
+ { 59, 69 },{ 60, 26 },{ 26, 14 },{ 16, 31 },{ 52, 78 },{ 23, 5 },{ 74, 37 },{ 53, 40 },
+ { 41, 27 },{ 13, 46 },{ 74, 73 },{ 72, 20 },{ 24, 38 },{ 19, 72 },{ 46, 11 },{ 55, 62 },
+ { 34, 55 },{ 10, 60 },{ 36, 6 },{ 77, 27 },{ 0, 78 },{ 42, 37 },{ 62, 37 },{ 57, 5 },
+ { 78, 44 },{ 37, 22 },{ 13, 11 },{ 62, 54 },{ 45, 55 },{ 27, 68 },{ 68, 11 },{ 25, 27 },
+ { 2, 60 },{ 28, 46 },{ 57, 31 },{ 9, 34 },{ 39, 72 },{ 78, 17 },{ 68, 69 },{ 17, 49 },
+ { 52, 17 },{ 47, 46 },{ 1, 6 },{ 21, 76 },{ 34, 29 },{ 71, 49 },{ 46, 0 },{ 7, 24 },
+ { 16, 61 },{ 65, 61 },{ 50, 68 },{ 8, 70 },{ 29, 12 },{ 70, 26 },{ 56, 18 },{ 36, 47 },
+ { 38, 64 },{ 5, 51 },{ 48, 28 },{ 16, 15 },{ 65, 2 },{ 64, 45 },{ 15, 38 },{ 26, 61 },
+ { 40, 19 },{ 8, 2 },{ 74, 57 },{ 52, 37 },{ 25, 33 },{ 3, 37 },{ 49, 4 },{ 0, 70 },
+ { 33, 0 },{ 23, 18 },{ 70, 14 },{ 56, 50 },{ 44, 64 },{ 72, 30 },{ 59, 74 },{ 22, 51 },
+ { 6, 16 },{ 38, 11 },{ 40, 43 },{ 21, 66 },{ 15, 2 },{ 9, 43 },{ 58, 39 },{ 70, 76 },
+ { 35, 37 },{ 59, 10 },{ 22, 25 },{ 56, 66 },{ 30, 5 },{ 33, 60 },{ 51, 24 },{ 69, 62 },
+ { 9, 56 },{ 0, 11 },{ 48, 50 },{ 62, 23 },{ 13, 75 },{ 41, 76 },{ 11, 26 },{ 0, 41 },
+ { 30, 40 },{ 75, 3 },{ 29, 18 },{ 66, 55 },{ 18, 55 },{ 69, 33 },{ 31, 74 },{ 44, 18 },
+ { 76, 65 },{ 40, 34 },{ 12, 7 },{ 48, 61 },{ 53, 1 },{ 77, 22 },{ 18, 30 },{ 64, 42 },
+ { 27, 52 },{ 26, 6 },{ 57, 16 },{ 58, 58 },{ 16, 66 },{ 1, 56 },{ 67, 7 },{ 31, 26 },
+ { 21, 40 },{ 52, 72 },{ 3, 31 },{ 45, 32 },{ 39, 59 },{ 42, 6 },{ 2, 71 },{ 74, 48 },
+ { 20, 3 },{ 16, 22 },{ 61, 32 },{ 62, 68 },{ 75, 9 },{ 10, 47 },{ 29, 65 },{ 52, 53 },
+ { 32, 45 },{ 33, 15 },{ 54, 29 },{ 12, 35 },{ 24, 75 },{ 48, 10 },{ 7, 65 },{ 68, 22 },
+ { 44, 46 },{ 2, 17 },{ 5, 3 },{ 35, 71 },{ 73, 69 },{ 52, 42 },{ 59, 3 },{ 70, 45 },
+ { 20, 10 },{ 21, 47 },{ 47, 71 },{ 31, 33 },{ 4, 42 },{ 64, 15 },{ 14, 58 },{ 38, 17 },
+ { 43, 58 },{ 75, 29 },{ 65, 49 },{ 63, 75 },{ 9, 12 },{ 44, 27 },{ 36, 53 },{ 11, 72 },
+ { 26, 21 },{ 35, 4 },{ 65, 38 },{ 5, 25 },{ 77, 63 },{ 25, 56 },{ 49, 36 },{ 54, 9 },
+ { 73, 78 },{ 59, 55 },{ 4, 54 },{ 21, 35 },{ 56, 24 },{ 28, 0 },{ 11, 20 },{ 39, 66 },
+ { 27, 43 },{ 14, 69 },{ 74, 39 },{ 46, 16 },{ 20, 16 },{ 54, 60 },{ 63, 8 },{ 38, 28 },
+ { 67, 28 },{ 66, 71 },{ 5, 77 },{ 56, 46 },{ 42, 3 },{ 15, 44 },{ 41, 50 },{ 75, 15 },
+ { 70, 59 },{ 8, 38 },{ 21, 70 },{ 34, 21 },{ 30, 61 },{ 15, 9 },{ 47, 75 },{ 44, 39 },
+ { 4, 47 },{ 13, 29 },{ 62, 19 },{ 53, 66 },{ 4, 7 },{ 76, 34 },{ 7, 59 },{ 42, 12 },
+ { 30, 48 },{ 56, 0 },{ 56, 41 },{ 76, 75 },{ 28, 32 },{ 23, 0 },{ 21, 62 },{ 48, 23 },
+ { 63, 51 },{ 1, 21 },{ 36, 74 },{ 77, 51 },{ 46, 52 },{ 69, 8 },{ 17, 26 },{ 32, 10 },
+ { 14, 51 },{ 63, 28 },{ 63, 65 },{ 38, 42 },{ 11, 77 },{ 24, 12 },{ 53, 14 },{ 3, 68 },
+ { 35, 66 },{ 55, 33 },{ 17, 34 },{ 71, 18 },{ 21, 54 },{ 67, 1 },{ 47, 57 },{ 76, 45 },
+ { 35, 33 },{ 49, 6 },{ 8, 14 },{ 44, 70 },{ 71, 55 },{ 12, 63 },{ 28, 24 },{ 0, 26 },
+ { 59, 61 },{ 29, 70 },{ 77, 4 },{ 50, 48 },{ 38, 8 },{ 24, 41 },{ 70, 37 },{ 43, 23 },
+ { 20, 6 },{ 60, 76 },{ 8, 51 },{ 32, 50 },{ 9, 30 },{ 69, 66 },{ 53, 21 },{ 17, 74 },
+ { 60, 41 },{ 13, 17 },{ 57, 12 },{ 34, 58 },{ 78, 58 },{ 44, 35 },{ 39, 78 },{ 1, 38 },
+ { 23, 23 },{ 76, 11 },{ 49, 63 },{ 1, 76 },{ 33, 38 },{ 72, 24 },{ 14, 41 },{ 27, 75 },
+ { 58, 71 },{ 59, 33 },{ 20, 58 },{ 28, 16 },{ 13, 4 },{ 64, 57 },{ 46, 3 },{ 35, 27 },
+ { 4, 62 },{ 61, 7 },{ 68, 48 },{ 38, 45 },{ 4, 34 },{ 49, 30 },{ 24, 66 },{ 3, 13 },
+ { 42, 62 },{ 36, 13 },{ 76, 68 },{ 19, 43 },{ 65, 21 },{ 54, 52 },{ 9, 22 },{ 8, 74 },
+ { 53, 75 },{ 73, 33 },{ 28, 54 },{ 21, 29 },{ 47, 39 },{ 68, 77 },{ 30, 2 },{ 7, 45 },
+ { 60, 17 },{ 61, 47 },{ 9, 7 },{ 38, 69 },{ 47, 18 },{ 26, 37 },{ 11, 68 },{ 65, 35 },
+ { 74, 61 },{ 41, 54 },{ 24, 8 },{ 53, 4 },{ 72, 9 },{ 18, 52 },{ 41, 31 },{ 18, 20 },
+ { 1, 48 },{ 47, 67 },{ 76, 19 },{ 19, 77 },{ 58, 25 },{ 57, 63 },{ 33, 18 },{ 69, 41 },
+ { 26, 58 },{ 71, 74 },{ 44, 10 },{ 15, 36 },{ 37, 49 },{ 11, 56 },{ 51, 35 },{ 1, 2 },
+ { 43, 75 },{ 5, 29 },{ 67, 60 },{ 17, 11 },{ 68, 15 },{ 51, 56 },{ 39, 21 },{ 19, 65 },
+ { 72, 51 },{ 24, 31 },{ 34, 76 },{ 50, 43 },{ 63, 3 },{ 77, 31 },{ 6, 68 },{ 30, 8 },
+ { 10, 40 },{ 52, 27 },{ 60, 67 },{ 24, 50 },{ 50, 13 },{ 35, 41 },{ 8, 18 },{ 24, 72 },
+ { 74, 1 },{ 76, 54 },{ 37, 56 },{ 67, 25 },{ 32, 25 },{ 52, 70 },{ 59, 45 },{ 16, 0 },
+ { 13, 61 },{ 22, 15 },{ 76, 40 },{ 50, 0 },{ 44, 48 },{ 38, 3 },{ 61, 11 },{ 10, 28 },
+ { 30, 67 },{ 59, 37 },{ 19, 48 },{ 6, 8 },{ 67, 68 },{ 33, 35 },{ 57, 56 },{ 4, 73 },
+ { 44, 21 },{ 6, 53 },{ 3, 23 },{ 43, 66 },{ 20, 23 },{ 65, 29 },{ 28, 42 },{ 55, 7 },
+ { 0, 65 },{ 34, 8 },{ 5, 39 },{ 66, 44 },{ 72, 15 },{ 27, 63 },{ 46, 29 },{ 64, 72 },
+ { 16, 7 },{ 20, 38 },{ 55, 48 },{ 57, 20 },{ 41, 39 },{ 6, 1 },{ 12, 48 },{ 43, 1 },
+ { 68, 54 },{ 41, 15 },{ 31, 59 },{ 70, 5 },{ 26, 3 },{ 15, 24 },{ 50, 60 },{ 3, 58 },
+ { 71, 28 },{ 29, 30 },{ 15, 71 },{ 57, 75 },{ 4, 15 },{ 54, 36 },{ 73, 43 },{ 38, 61 },
+ { 71, 64 },{ 30, 21 },{ 15, 55 },{ 41, 46 },{ 54, 16 },{ 12, 14 },{ 32, 72 },{ 77, 6 },
+ { 61, 52 },{ 12, 33 },{ 49, 73 },{ 38, 24 },{ 1, 44 },{ 30, 51 },{ 61, 25 },{ 75, 71 },
+ { 27, 12 },{ 64, 0 },{ 10, 65 },{ 74, 25 },{ 45, 43 },{ 47, 8 },{ 25, 44 },{ 20, 74 },
+ { 62, 59 },{ 23, 34 },{ 67, 34 },{ 44, 56 },{ 65, 11 },{ 18, 17 },{ 34, 2 },{ 12, 44 },
+ { 50, 26 },{ 10, 0 },{ 38, 34 },{ 2, 35 },{ 22, 61 },{ 56, 69 },{ 1, 10 },{ 51, 50 },
+ { 1, 53 },{ 37, 71 },{ 45, 14 },{ 59, 30 },{ 6, 22 },{ 77, 78 },{ 24, 20 },{ 25, 69 },
+ { 57, 2 },{ 66, 40 },{ 33, 53 },{ 72, 58 },{ 22, 3 },{ 36, 30 },{ 69, 17 },{ 16, 59 },
+ { 51, 39 },{ 40, 7 },{ 69, 72 },{ 17, 39 },{ 49, 66 },{ 1, 30 },{ 9, 50 },{ 31, 16 },
+ { 59, 15 },{ 9, 72 },{ 53, 58 },{ 32, 43 },{ 12, 9 },{ 72, 47 },{ 36, 64 },{ 75, 20 },
+ { 18, 28 },{ 65, 64 },{ 51, 22 },{ 45, 76 },{ 7, 63 },{ 47, 33 },{ 71, 2 },{ 23, 53 },
+ { 27, 26 },{ 7, 35 },{ 44, 51 },{ 27, 78 },{ 63, 39 },{ 59, 6 },{ 17, 67 },{ 64, 53 },
+ { 37, 15 },{ 1, 73 },{ 13, 19 },{ 71, 32 },{ 28, 39 },{ 41, 60 },{ 22, 11 },{ 3, 49 },
+ { 61, 21 },{ 51, 3 },{ 55, 43 },{ 77, 61 },{ 42, 29 },{ 73, 12 },{ 40, 74 },{ 20, 45 },
+ { 12, 3 },{ 61, 71 },{ 9, 25 },{ 32, 62 },{ 54, 31 },{ 35, 49 },{ 73, 67 },{ 27, 7 },
+ { 75, 36 },{ 50, 11 },{ 54, 64 },{ 3, 19 },{ 8, 57 },{ 48, 47 },{ 19, 33 },{ 5, 5 },
+ { 29, 74 },{ 42, 20 },{ 6, 42 },{ 64, 6 },{ 59, 49 },{ 40, 36 },{ 15, 76 },{ 75, 50 },
+ { 43, 69 },{ 67, 20 },{ 23, 27 },{ 24, 57 },{ 66, 76 },{ 36, 9 },{ 16, 50 },{ 78, 25 },
+ { 62, 34 },{ 49, 54 },{ 18, 4 },{ 35, 23 },{ 3, 66 },{ 61, 62 },{ 29, 35 },{ 55, 11 },
+ { 37, 77 },{ 78, 13 },{ 16, 64 },{ 67, 50 },{ 12, 37 },{ 54, 23 },{ 54, 77 },{ 40, 52 },
+ { 15, 16 },{ 73, 76 },{ 77, 43 },{ 34, 68 },{ 30, 46 },{ 27, 17 },{ 45, 40 },{ 45, 5 },
+ { 75, 56 },{ 6, 75 },{ 69, 10 },{ 8, 32 },{ 46, 63 },{ 57, 38 },{ 22, 69 },{ 49, 18 },
+ { 6, 13 },{ 12, 52 },{ 72, 38 },{ 33, 28 },{ 60, 0 },{ 33, 5 },{ 57, 53 },{ 71, 22 },
+ { 29, 55 },{ 78, 69 },{ 14, 27 },{ 36, 39 },{ 43, 25 },{ 0, 5 },{ 22, 78 },{ 68, 63 },
+ { 63, 26 },{ 22, 46 },{ 50, 72 },{ 62, 43 },{ 19, 14 },{ 5, 59 },{ 40, 12 },{ 25, 63 },
+ { 64, 17 },{ 2, 27 },{ 35, 57 },{ 10, 45 },{ 51, 45 },{ 58, 67 },{ 9, 5 },{ 31, 11 },
+ { 26, 31 },{ 13, 68 },{ 52, 31 },{ 47, 1 },{ 69, 46 },{ 68, 4 },{ 45, 59 },{ 0, 36 },
+ { 19, 56 },{ 22, 20 },{ 37, 44 },{ 67, 56 },{ 51, 15 },{ 2, 1 },{ 23, 39 },{ 26, 73 },
+ { 68, 29 },{ 19, 7 },{ 55, 57 },{ 76, 17 },{ 41, 78 },{ 1, 62 },{ 46, 35 },{ 14, 31 },
+ { 65, 69 },{ 37, 18 },{ 0, 46 },{ 62, 14 },{ 33, 65 },{ 11, 74 },{ 17, 43 },{ 56, 29 },
+ { 57, 73 },{ 12, 22 },{ 27, 49 },{ 51, 7 },{ 39, 26 },{ 42, 65 },{ 11, 12 },{ 3, 55 },
+ { 48, 42 },{ 31, 0 },{ 74, 30 },{ 72, 70 },{ 14, 60 },{ 76, 8 },{ 31, 23 },{ 64, 47 },
+ { 39, 56 },{ 3, 40 },{ 47, 22 },{ 51, 67 },{ 32, 39 },{ 18, 71 },{ 61, 9 },{ 6, 19 },
+ { 60, 57 },{ 25, 5 },{ 63, 36 },{ 76, 0 },{ 42, 9 },{ 19, 25 },{ 7, 69 },{ 42, 45 },
+ { 57, 23 },{ 71, 61 },{ 28, 66 },{ 8, 41 },{ 63, 77 },{ 32, 31 },{ 0, 22 },{ 47, 53 },
+ { 44, 72 },{ 73, 41 },{ 13, 1 },{ 14, 49 },{ 34, 14 },{ 68, 13 },{ 57, 42 },{ 25, 52 },
+ { 25, 15 },{ 78, 53 },{ 54, 5 },{ 4, 10 },{ 25, 35 },{ 20, 64 },{ 64, 31 },{ 33, 75 },
+ { 42, 34 },{ 64, 60 },{ 5, 32 },{ 69, 0 },{ 54, 19 },{ 53, 51 },{ 16, 12 },{ 40, 4 },
+ { 9, 59 },{ 34, 46 },{ 17, 37 },{ 51, 76 },{ 76, 73 },{ 66, 23 },{ 40, 68 },{ 71, 52 },
+ { 27, 22 },{ 47, 31 },{ 18, 78 },{ 78, 32 },{ 27, 59 },{ 52, 60 },{ 47, 15 },{ 6, 47 },
+ { 0, 16 },{ 3, 77 },{ 40, 41 },{ 75, 63 },{ 56, 34 },{ 29, 7 },{ 8, 26 },{ 62, 66 },
+ { 37, 52 },{ 58, 13 },{ 21, 42 },{ 30, 69 },{ 69, 43 },{ 72, 7 },{ 11, 62 },{ 35, 20 },
+ { 17, 21 },{ 54, 70 },{ 54, 47 },{ 8, 9 },{ 20, 53 },{ 36, 2 },{ 69, 35 },{ 46, 25 },
+ { 22, 32 },{ 60, 4 },{ 4, 69 },{ 75, 26 },{ 32, 57 },{ 50, 38 },{ 67, 73 },{ 23, 76 },
+ { 11, 39 },{ 45, 12 },{ 48, 58 },{ 76, 47 },{ 36, 35 },{ 21, 9 },{ 61, 28 },{ 9, 54 },
+ { 46, 69 },{ 9, 16 },{ 60, 53 },{ 26, 46 },{ 71, 16 },{ 16, 73 },{ 40, 16 },{ 77, 57 },
+ { 55, 1 },{ 26, 28 },{ 37, 62 },{ 7, 3 },{ 60, 39 },{ 4, 26 },{ 57, 61 },{ 18, 59 },
+ { 63, 20 },{ 40, 48 },{ 71, 68 },{ 28, 13 },{ 16, 33 },{ 47, 5 },{ 40, 29 },{ 78, 39 },
+ { 37, 73 },{ 75, 5 },{ 16, 46 },{ 16, 3 },{ 55, 26 },{ 78, 67 },{ 65, 51 },{ 67, 9 },
+ { 23, 65 },{ 21, 18 },{ 42, 55 },{ 30, 38 },{ 27, 1 },{ 53, 10 },{ 4, 50 },{ 69, 27 },
+ { 46, 45 },{ 61, 75 },{ 10, 70 },{ 11, 29 },{ 46, 74 },{ 62, 46 },{ 2, 12 },{ 34, 26 },
+ { 68, 59 },{ 31, 49 },{ 37, 6 },{ 73, 21 },{ 13, 56 },{ 49, 25 },{ 6, 37 },{ 14, 8 },
+ { 55, 65 },{ 29, 62 },{ 54, 41 },{ 78, 76 },{ 32, 20 },{ 72, 34 },{ 58, 17 },{ 23, 71 },
+ { 4, 64 },{ 24, 25 },{ 66, 3 },{ 43, 38 },{ 13, 42 },{ 42, 0 },{ 47, 62 },{ 73, 50 },
+ { 15, 19 },{ 8, 77 },{ 21, 49 },{ 45, 19 },{ 66, 66 },{ 37, 67 },{ 68, 40 },{ 49, 51 },
+ { 74, 10 },{ 30, 32 },{ 27, 10 },{ 15, 67 },{ 3, 44 },{ 52, 34 },{ 57, 77 },{ 2, 20 },
+ { 34, 42 },{ 30, 72 },{ 66, 15 },{ 1, 59 },{ 37, 12 },{ 57, 49 },{ 17, 29 },{ 72, 75 },
+ { 35, 54 },{ 49, 9 },{ 21, 5 },{ 60, 31 },{ 10, 35 },{ 59, 63 },{ 2, 7 },{ 24, 60 },
+ { 25, 42 },{ 72, 56 },{ 49, 78 },{ 39, 32 },{ 77, 29 },{ 10, 18 },{ 52, 20 },{ 42, 59 },
+ { 7, 52 },{ 31, 4 },{ 3, 72 },{ 67, 32 },{ 63, 10 },{ 40, 23 },{ 54, 55 },{ 12, 76 },
+ { 74, 44 },{ 23, 13 },{ 40, 71 },{ 20, 36 },{ 60, 70 },{ 17, 62 },{ 48, 38 },{ 74, 18 },
+ { 29, 52 },{ 64, 55 },{ 14, 23 },{ 60, 23 },{ 9, 64 },{ 44, 7 },{ 72, 1 },{ 45, 50 },
+ { 28, 20 },{ 10, 49 },{ 11, 6 },{ 65, 43 },{ 32, 76 },{ 56, 6 },{ 2, 32 },{ 29, 44 },
+ { 45, 28 },{ 73, 65 },{ 50, 65 },{ 20, 0 },{ 35, 60 },{ 5, 23 },{ 34, 34 },{ 58, 36 },
+ { 62, 1 },{ 15, 52 },{ 44, 16 },{ 4, 2 },{ 70, 23 },{ 18, 41 },{ 32, 13 },{ 57, 45 },
+ { 52, 74 },{ 26, 67 },{ 78, 49 },{ 21, 26 },{ 68, 71 },{ 56, 15 },{ 43, 42 },{ 13, 15 },
+ { 21, 57 },{ 74, 35 },{ 38, 0 },{ 75, 60 },{ 45, 65 },{ 77, 12 },{ 37, 27 },{ 5, 56 },
+ { 53, 28 },{ 20, 69 },{ 6, 28 },{ 39, 50 },{ 63, 58 },{ 24, 1 },{ 66, 18 },{ 27, 36 },
+ { 0, 72 },{ 45, 2 },{ 70, 48 },{ 19, 11 },{ 8, 44 },{ 33, 69 },{ 51, 47 },{ 65, 7 },
+ { 14, 35 },{ 38, 20 },{ 3, 16 },{ 27, 55 },{ 63, 73 },{ 66, 37 },{ 7, 72 },{ 38, 39 },
+ { 33, 9 },{ 49, 56 },{ 64, 25 },{ 29, 25 },{ 13, 65 },{ 48, 69 },{ 2, 39 },{ 54, 12 },
+ { 76, 2 },{ 68, 52 },{ 19, 50 },{ 8, 11 },{ 49, 32 },{ 26, 76 },{ 64, 63 },{ 20, 30 },
+ { 52, 2 },{ 40, 61 },{ 70, 12 },{ 25, 18 },{ 61, 42 },{ 78, 23 },{ 34, 48 },{ 78, 64 },
+ { 48, 20 },{ 15, 4 },{ 39, 9 },{ 77, 41 },{ 55, 72 },{ 25, 47 },{ 51, 41 },{ 12, 27 },
+ { 8, 61 },{ 70, 77 },{ 59, 27 },{ 19, 75 },{ 56, 55 },{ 36, 76 },{ 14, 45 },{ 43, 31 },
+ { 72, 26 },{ 30, 58 },{ 32, 17 },{ 9, 1 },{ 74, 53 },{ 53, 63 },{ 19, 22 },{ 58, 11 },
+ { 31, 41 },{ 75, 69 },{ 8, 36 },{ 62, 49 },{ 43, 77 },{ 16, 56 },{ 0, 9 },{ 61, 18 },
+ { 42, 52 },{ 24, 7 },{ 70, 39 },{ 35, 31 },{ 58, 1 },{ 16, 69 },{ 7, 21 },{ 40, 65 },
+ { 43, 11 },{ 22, 38 },{ 55, 37 },{ 2, 54 },{ 69, 65 },{ 15, 11 },{ 50, 17 },{ 31, 66 },
+ { 73, 31 },{ 39, 44 },{ 69, 6 },{ 5, 67 },{ 29, 3 },{ 57, 68 },{ 30, 28 },{ 5, 46 },
+ { 58, 32 },{ 1, 4 },{ 10, 32 },{ 47, 48 },{ 21, 60 },{ 42, 24 },{ 58, 60 },{ 17, 16 },
+ { 48, 74 },{ 70, 19 },{ 18, 47 },{ 10, 75 },{ 66, 47 },{ 34, 6 },{ 45, 36 },{ 65, 77 },
+ { 32, 55 },{ 0, 34 },{ 27, 70 },{ 58, 21 },{ 7, 15 },{ 70, 56 },{ 24, 29 },{ 50, 8 },
+ { 45, 57 },{ 11, 54 },{ 74, 75 },{ 41, 18 },{ 16, 40 },{ 77, 20 },{ 36, 70 },{ 50, 28 },
+ { 4, 60 },{ 24, 22 },{ 55, 51 },{ 64, 13 },{ 16, 77 },{ 63, 32 },{ 27, 41 },{ 64, 68 },
+ { 41, 5 },{ 10, 8 },{ 1, 42 },{ 38, 57 },{ 29, 15 },{ 4, 78 },{ 38, 37 },{ 23, 55 },
+ { 4, 30 },{ 42, 71 },{ 64, 4 },{ 53, 45 },{ 72, 45 },{ 10, 24 },{ 20, 67 },{ 66, 27 },
+ { 51, 61 },{ 23, 10 },{ 0, 57 },{ 73, 14 },{ 47, 12 },{ 30, 34 },{ 66, 62 },{ 25, 74 },
+ { 64, 40 },{ 52, 23 },{ 15, 62 },{ 59, 77 },{ 37, 46 },{ 16, 25 },{ 2, 74 },{ 32, 1 },
+ { 23, 44 },{ 52, 68 },{ 76, 37 },{ 34, 24 },{ 72, 4 },{ 33, 63 },{ 47, 43 },{ 2, 50 },
+ { 57, 7 },{ 8, 66 },{ 61, 55 },{ 17, 8 },{ 1, 25 },{ 36, 17 },{ 12, 41 },{ 53, 35 },
+ { 46, 77 },{ 5, 9 },{ 26, 51 },{ 72, 62 },{ 18, 32 },{ 70, 31 },{ 43, 63 },{ 45, 22 },
+ { 70, 73 },{ 51, 54 },{ 19, 2 },{ 55, 17 },{ 13, 72 },{ 41, 35 },{ 9, 48 },{ 77, 16 },
+ { 48, 3 },{ 22, 17 },{ 60, 46 },{ 24, 62 },{ 24, 36 },{ 39, 76 },{ 63, 22 },{ 11, 59 },
+ { 60, 65 },{ 36, 51 },{ 30, 10 },{ 61, 36 },{ 0, 0 },{ 10, 21 },{ 4, 38 },{ 41, 13 },
+ { 59, 72 },{ 43, 47 },{ 75, 46 },{ 30, 75 },{ 60, 8 },{ 1, 69 },{ 37, 29 },{ 17, 54 },
+ { 75, 23 },{ 34, 39 },{ 67, 53 },{ 71, 8 },{ 28, 64 },{ 55, 30 },{ 11, 13 },{ 13, 32 },
+ { 37, 4 },{ 74, 59 },{ 45, 53 },{ 21, 72 },{ 26, 23 },{ 54, 0 },{ 57, 40 },{ 29, 47 },
+ { 6, 4 },{ 76, 28 },{ 49, 14 },{ 44, 67 },{ 6, 57 },{ 43, 28 },{ 67, 75 },{ 24, 4 },
+ { 59, 51 },{ 11, 46 },{ 61, 15 },{ 72, 36 },{ 12, 78 },{ 36, 59 },{ 28, 30 },{ 4, 17 },
+ { 68, 44 },{ 35, 12 },{ 70, 67 },{ 19, 37 },{ 51, 71 },{ 48, 36 },{ 3, 63 },{ 20, 15 },
+ { 68, 19 },{ 33, 71 },{ 55, 59 },{ 23, 50 },{ 8, 29 },{ 68, 2 },{ 54, 25 },{ 77, 52 },
+ { 51, 5 },{ 12, 69 },{ 36, 43 },{ 32, 22 },{ 77, 9 },{ 9, 39 },{ 49, 59 },{ 66, 33 },
+ { 19, 62 },{ 41, 2 },{ 14, 18 },{ 32, 52 },{ 74, 70 },{ 44, 41 },{ 26, 9 },{ 62, 61 },
+ { 48, 27 },{ 67, 12 },{ 37, 65 },{ 11, 51 },{ 22, 28 },{ 13, 5 },{ 72, 42 },{ 56, 74 },
+ { 43, 19 },{ 68, 25 },{ 49, 46 },{ 5, 74 },{ 27, 57 },{ 3, 34 },{ 45, 9 },{ 32, 37 },
+ { 26, 0 },{ 68, 57 },{ 5, 14 },{ 20, 44 },{ 58, 4 },{ 59, 42 },{ 46, 72 },{ 77, 66 },
+ { 16, 27 },{ 56, 22 },{ 3, 45 },{ 18, 66 },{ 40, 55 },{ 30, 17 },{ 3, 6 },{ 53, 38 },
+ { 34, 78 },{ 74, 16 },{ 58, 54 },{ 14, 57 },{ 1, 28 },{ 37, 23 },{ 64, 71 },{ 15, 74 },
+ { 27, 38 },{ 60, 29 },{ 53, 8 },{ 4, 52 },{ 48, 64 },{ 20, 20 },{ 74, 0 },{ 29, 68 },
+ { 41, 32 },{ 70, 51 },{ 14, 38 },{ 18, 6 },{ 52, 15 },{ 52, 48 },{ 41, 74 },{ 76, 33 },
+ { 31, 45 },{ 8, 68 },{ 38, 14 },{ 66, 10 },{ 1, 18 },{ 32, 61 },{ 78, 60 },{ 55, 67 },
+ { 16, 48 },{ 67, 39 },{ 31, 6 },{ 21, 33 },{ 15, 14 },{ 50, 34 },{ 77, 76 },{ 22, 75 },
+ { 60, 20 },{ 64, 50 },{ 33, 30 },{ 43, 60 },{ 5, 41 },{ 63, 1 },{ 8, 23 },{ 41, 43 },
+ { 50, 77 },{ 22, 64 },{ 70, 29 },{ 8, 0 },{ 74, 55 },{ 47, 24 },{ 25, 13 },{ 74, 6 },
+ { 19, 54 },{ 61, 69 },{ 48, 52 },{ 41, 8 },{ 78, 47 },{ 15, 30 },{ 39, 70 },{ 62, 27 },
+ { 70, 63 },{ 30, 24 },{ 11, 64 },{ 38, 48 },{ 60, 12 },{ 13, 10 },{ 22, 41 },{ 56, 44 },
+ { 28, 76 },{ 70, 21 },{ 61, 58 },{ 6, 31 },{ 42, 26 },{ 25, 59 },{ 3, 11 },{ 52, 57 },
+ { 6, 71 },{ 53, 18 },{ 35, 7 },{ 8, 53 },{ 21, 24 },{ 61, 38 },{ 71, 71 },{ 36, 55 },
+ { 75, 40 },{ 17, 2 },{ 51, 1 },{ 37, 33 },{ 71, 13 },{ 24, 70 },{ 27, 45 },{ 62, 6 },
+ { 34, 17 },{ 7, 43 },{ 47, 40 },{ 56, 64 },{ 9, 19 },{ 78, 3 },{ 63, 44 },{ 35, 74 },
+ { 27, 33 },{ 6, 63 },{ 56, 32 },{ 44, 13 },{ 30, 54 },{ 3, 25 },{ 62, 76 },{ 41, 64 },
+ { 22, 6 },{ 69, 60 },{ 14, 43 },{ 73, 23 },{ 46, 31 },{ 76, 49 },{ 44, 2 },{ 10, 3 },
+ { 43, 50 },{ 11, 34 },{ 56, 13 },{ 10, 57 },{ 77, 72 },{ 26, 16 },{ 64, 35 },{ 48, 68 },
+ { 18, 73 },{ 65, 16 },{ 34, 36 },{ 22, 52 },{ 17, 23 },{ 65, 56 },{ 50, 20 },{ 34, 65 },
+ { 69, 78 },{ 0, 37 },{ 28, 5 },{ 57, 48 },{ 75, 12 },{ 39, 40 },{ 0, 63 },{ 39, 18 },
+ { 48, 7 },{ 46, 56 },{ 74, 28 },{ 20, 12 },{ 14, 53 },{ 64, 66 },{ 7, 7 },{ 57, 26 },
+ { 16, 35 },{ 35, 1 },{ 32, 48 },{ 53, 71 },{ 14, 66 },{ 70, 42 },{ 26, 26 },{ 7, 76 },
+ { 30, 63 },{ 52, 43 },{ 12, 24 },{ 0, 54 },{ 56, 3 },{ 66, 24 },{ 25, 39 },{ 44, 74 },
+ { 1, 15 },{ 43, 36 },{ 67, 70 },{ 7, 49 },{ 36, 21 },{ 40, 58 },{ 70, 34 },{ 24, 78 },
+ { 67, 5 },{ 67, 48 },{ 22, 58 },{ 37, 10 },{ 52, 30 },{ 12, 16 },{ 54, 61 },{ 2, 67 },
+ { 32, 27 },{ 19, 46 },{ 31, 71 },{ 0, 31 },{ 14, 0 },{ 46, 17 },{ 53, 53 },{ 74, 64 },
+ { 63, 18 },{ 73, 2 },{ 33, 44 },{ 5, 20 },{ 58, 75 },{ 25, 67 },{ 0, 43 },{ 45, 47 },
+ { 23, 21 },{ 52, 11 },{ 12, 60 },{ 58, 34 },{ 39, 2 },{ 2, 78 },{ 7, 34 },{ 62, 52 },
+ { 45, 62 },{ 24, 33 },{ 28, 11 },{ 25, 49 },{ 65, 30 },{ 0, 7 },{ 72, 53 },{ 39, 27 },
+ { 42, 68 },{ 10, 73 },{ 50, 23 },{ 9, 27 },{ 59, 66 },{ 16, 10 },{ 17, 51 },{ 57, 10 },
+ { 38, 53 },{ 76, 21 },{ 29, 1 },{ 2, 57 },{ 54, 39 },{ 48, 0 },{ 10, 42 },{ 70, 9 },
+ { 18, 69 },{ 28, 19 },{ 65, 41 },{ 73, 74 },{ 29, 59 },{ 45, 33 },{ 65, 59 },{ 29, 41 },
+ { 7, 12 },{ 53, 76 },{ 19, 29 },{ 49, 49 },{ 59, 24 },{ 43, 5 },{ 73, 38 },{ 17, 60 },
+ { 17, 19 },{ 58, 57 },{ 35, 69 },{ 41, 21 },{ 2, 48 },{ 69, 16 },{ 22, 2 },{ 66, 0 },
+ { 32, 34 },{ 3, 70 },{ 18, 39 },{ 34, 11 },{ 50, 62 },{ 71, 46 },{ 33, 56 },{ 1, 23 },
+ { 68, 67 },{ 42, 40 },{ 61, 4 },{ 27, 73 },{ 7, 38 },{ 56, 19 },{ 8, 4 },{ 76, 58 },
+ { 60, 48 },{ 43, 15 },{ 13, 48 },{ 38, 73 },{ 68, 31 },{ 23, 14 },{ 26, 53 },{ 49, 41 },
+ { 14, 70 },{ 62, 72 },{ 28, 28 },{ 73, 19 },{ 12, 30 },{ 39, 62 },{ 48, 29 },{ 7, 60 },
+ { 2, 3 },{ 48, 72 },{ 62, 10 },{ 20, 8 },{ 40, 46 },{ 77, 36 },{ 7, 17 },{ 38, 31 },
+ { 74, 68 },{ 49, 12 },{ 56, 52 },{ 20, 77 },{ 23, 42 },{ 52, 65 },{ 71, 25 },{ 31, 14 },
+ { 22, 67 },{ 73, 49 },{ 61, 33 },{ 34, 50 },{ 0, 75 },{ 13, 21 },{ 40, 77 },{ 6, 54 },
+ { 73, 10 },{ 44, 54 },{ 13, 36 },{ 54, 6 },{ 52, 26 },{ 62, 63 },{ 33, 4 },{ 10, 67 },
+ { 36, 38 },{ 4, 27 },{ 65, 46 },{ 11, 8 },{ 19, 58 },{ 33, 20 },{ 60, 78 },{ 66, 21 },
+ { 71, 58 },{ 35, 62 },{ 22, 31 },{ 51, 37 },{ 17, 44 },{ 69, 75 },{ 39, 7 },{ 13, 77 },
+ { 76, 43 },{ 0, 13 },{ 45, 26 },{ 46, 66 },{ 59, 40 },{ 27, 62 },{ 17, 14 },{ 59, 14 },
+ { 5, 48 },{ 29, 49 },{ 57, 70 },{ 3, 61 },{ 30, 78 },{ 76, 30 },{ 37, 25 },{ 50, 55 },
+ { 46, 6 },{ 68, 36 },{ 76, 5 },{ 28, 36 },{ 15, 63 },{ 45, 44 },{ 22, 22 },{ 5, 0 },
+ { 48, 17 },{ 65, 54 },{ 4, 35 },{ 62, 24 },{ 38, 67 },{ 76, 62 },{ 26, 8 },{ 23, 47 },
+ { 55, 78 },{ 14, 26 },{ 66, 8 },{ 55, 45 },{ 12, 55 },{ 23, 73 },{ 39, 35 },{ 15, 6 },
+ { 47, 59 },{ 78, 18 },{ 36, 15 },{ 0, 51 },{ 57, 29 },{ 19, 35 },{ 72, 77 },{ 58, 62 },
+ { 45, 78 },{ 35, 45 },{ 9, 45 },{ 9, 13 },{ 28, 69 },{ 64, 37 },{ 67, 65 },{ 43, 22 },
+ { 65, 14 },{ 6, 66 },{ 31, 30 },{ 6, 26 },{ 41, 51 },{ 51, 73 },{ 24, 55 },{ 41, 11 },
+ { 19, 17 },{ 1, 40 },{ 70, 3 },{ 51, 32 },{ 16, 75 },{ 69, 55 },{ 33, 74 },{ 52, 50 },
+ { 77, 26 },{ 58, 18 },{ 77, 70 },{ 33, 59 },{ 15, 40 },{ 31, 8 },{ 50, 4 },{ 27, 24 },
+ { 2, 8 },{ 46, 38 },{ 64, 74 },{ 20, 61 },{ 68, 45 },{ 64, 28 },{ 9, 71 },{ 31, 42 },
+ { 20, 4 },{ 45, 71 },{ 9, 33 },{ 56, 58 },{ 54, 13 },{ 20, 49 },{ 56, 36 },{ 77, 55 },
+ { 25, 30 },{ 75, 14 },{ 12, 2 },{ 42, 57 },{ 74, 33 },{ 36, 0 },{ 30, 20 },{ 10, 52 },
+ { 60, 2 },{ 60, 44 },{ 25, 64 },{ 47, 21 },{ 12, 19 },{ 68, 61 },{ 4, 76 },{ 36, 28 },
+ { 53, 69 },{ 3, 43 },{ 48, 45 },{ 47, 10 },{ 3, 22 },{ 20, 71 },{ 37, 42 },{ 77, 1 },
+ { 27, 3 },{ 67, 22 },{ 23, 37 },{ 8, 58 },{ 61, 60 },{ 19, 26 },{ 35, 52 },{ 72, 40 },
+ { 54, 22 },{ 41, 72 },{ 6, 11 },{ 72, 66 },{ 39, 16 },{ 59, 7 },{ 28, 56 },{ 61, 50 },
+ { 24, 11 },{ 11, 38 },{ 1, 65 },{ 72, 28 },{ 42, 30 },{ 34, 67 },{ 66, 72 },{ 15, 58 },
+ { 69, 14 },{ 47, 51 },{ 27, 15 },{ 74, 51 },{ 48, 76 },{ 26, 43 },{ 14, 12 },{ 54, 27 },
+ { 17, 65 },{ 2, 30 },{ 41, 38 },{ 73, 8 },{ 51, 59 },{ 36, 5 },{ 63, 41 },{ 14, 47 },
+ { 75, 74 },{ 17, 0 },{ 54, 2 },{ 15, 32 },{ 37, 60 },{ 77, 45 },{ 39, 22 },{ 65, 4 },
+ { 54, 42 },{ 29, 73 },{ 24, 19 },{ 61, 67 },{ 29, 33 },{ 64, 20 },{ 10, 63 },{ 5, 6 },
+ { 51, 16 },{ 20, 55 },{ 69, 49 },{ 78, 21 },{ 47, 34 },{ 49, 67 },{ 6, 40 },{ 12, 73 },
+ { 42, 4 },{ 15, 22 },{ 41, 48 },{ 63, 30 },{ 59, 56 },{ 20, 41 },{ 4, 71 },{ 31, 12 },
+ { 31, 51 },{ 62, 13 },{ 69, 37 },{ 55, 74 },{ 3, 51 },{ 23, 3 },{ 33, 26 },{ 78, 10 },
+ { 31, 68 },{ 73, 58 },{ 46, 14 },{ 54, 49 },{ 6, 24 },{ 33, 40 },{ 42, 76 },{ 54, 34 },
+ { 70, 69 },{ 11, 10 },{ 15, 50 },{ 2, 36 },{ 42, 61 },{ 72, 18 },{ 52, 8 },{ 9, 78 },
+ { 24, 26 },{ 33, 77 },{ 46, 27 },{ 5, 62 },{ 64, 76 },{ 68, 27 },{ 27, 47 },{ 63, 54 },
+ { 21, 65 },{ 13, 28 },{ 46, 54 },{ 34, 19 },{ 70, 1 },{ 11, 44 },{ 19, 9 },{ 50, 40 },
+ { 39, 68 },{ 0, 68 },{ 58, 23 },{ 3, 14 },{ 36, 34 },{ 57, 65 },{ 39, 12 },{ 28, 61 },
+ { 78, 33 },{ 17, 72 },{ 74, 45 },{ 20, 34 },{ 68, 7 },{ 60, 34 },{ 5, 55 },{ 29, 6 },
+ { 38, 55 },{ 47, 4 },{ 9, 17 },{ 60, 73 },{ 42, 43 },{ 66, 50 },{ 60, 16 },{ 24, 52 },
+ { 21, 16 },{ 76, 77 },{ 49, 24 },{ 46, 64 },{ 14, 3 },{ 8, 31 },{ 0, 59 },{ 58, 46 },
+ { 29, 39 },{ 25, 72 },{ 74, 24 },{ 55, 10 },{ 7, 46 },{ 36, 72 },{ 66, 63 },{ 40, 28 },
+ { 13, 62 },{ 71, 33 },{ 37, 8 },{ 52, 55 },{ 18, 22 },{ 21, 45 },{ 6, 2 },{ 43, 17 },
+ { 36, 48 },{ 64, 9 },{ 66, 42 },{ 51, 69 },{ 21, 78 },{ 73, 71 },{ 29, 23 },{ 50, 30 },
+ { 32, 64 },{ 78, 15 },{ 16, 37 },{ 75, 54 },{ 10, 69 },{ 57, 0 },{ 44, 37 },{ 75, 38 },
+ { 18, 53 },{ 4, 19 },{ 31, 2 },{ 55, 20 },{ 57, 51 },{ 26, 32 },{ 74, 4 },{ 44, 0 },
+ { 56, 39 },{ 73, 61 },{ 18, 12 },{ 33, 54 },{ 78, 28 },{ 55, 63 },{ 34, 31 },{ 68, 18 },
+ { 23, 61 },{ 7, 74 },{ 32, 15 },{ 1, 47 },{ 63, 69 },{ 44, 58 },{ 10, 26 },{ 46, 9 },
+ { 65, 32 },{ 11, 5 },{ 13, 51 },{ 50, 44 },{ 38, 77 },{ 9, 36 },{ 72, 11 },{ 41, 24 },
+ { 27, 66 },{ 52, 77 },{ 66, 57 },{ 23, 7 },{ 19, 31 },{ 1, 77 },{ 59, 28 },{ 31, 47 },
+ { 15, 68 },{ 51, 13 },{ 44, 49 },{ 5, 58 },{ 65, 1 },{ 14, 16 },{ 38, 63 },{ 78, 42 },
+ { 27, 18 },{ 18, 42 },{ 61, 22 },{ 76, 67 },{ 40, 33 },{ 47, 70 },{ 62, 45 },{ 26, 77 },
+ { 58, 5 },{ 36, 41 },{ 8, 8 },{ 69, 53 },{ 4, 33 },{ 48, 19 },{ 26, 56 },{ 54, 58 },
+ { 72, 22 },{ 7, 50 },{ 35, 14 },{ 21, 74 },{ 60, 37 },{ 76, 7 },{ 25, 37 },{ 60, 62 },
+ { 13, 59 },{ 23, 24 },{ 40, 3 },{ 68, 76 },{ 49, 35 },{ 8, 21 },{ 43, 67 },{ 71, 38 },
+ { 4, 67 },{ 57, 14 },{ 32, 58 },{ 26, 11 },{ 51, 52 },{ 12, 40 },{ 35, 25 },{ 57, 72 },
+ { 67, 30 },{ 14, 75 },{ 72, 48 },{ 2, 5 },{ 40, 45 },{ 16, 29 },{ 50, 2 },{ 22, 49 },
+ { 75, 18 },{ 34, 3 },{ 72, 64 },{ 31, 35 },{ 54, 32 },{ 24, 68 },{ 63, 7 },{ 10, 14 },
+ { 48, 60 },{ 10, 55 },{ 44, 20 },{ 5, 43 },{ 78, 73 },{ 32, 73 },{ 46, 41 },{ 67, 14 },
+ { 16, 20 },{ 40, 53 },{ 42, 10 },{ 66, 68 },{ 73, 29 },{ 16, 5 },{ 18, 57 },{ 60, 54 },
+ { 28, 44 },{ 53, 24 },{ 8, 64 },{ 43, 73 },{ 3, 29 },{ 70, 44 },{ 30, 27 },{ 1, 55 },
+ { 29, 9 },{ 45, 30 },{ 54, 66 },{ 4, 12 },{ 65, 24 },{ 34, 61 },{ 61, 77 },{ 16, 45 },
+ { 54, 46 },{ 38, 19 },{ 0, 1 },{ 21, 19 },{ 63, 38 },{ 18, 64 },{ 55, 8 },{ 13, 34 },
+ { 25, 1 },{ 66, 60 },{ 28, 53 },{ 0, 24 },{ 78, 62 },{ 49, 75 },{ 40, 37 },{ 62, 17 },
+ { 0, 39 },{ 36, 66 },{ 10, 77 },{ 21, 39 },{ 71, 4 },{ 46, 47 },{ 44, 6 },{ 22, 12 },
+ { 65, 48 },{ 21, 28 },{ 71, 73 },{ 55, 28 },{ 19, 70 },{ 76, 51 },{ 51, 63 },{ 5, 16 },
+ { 37, 50 },{ 53, 17 },{ 37, 75 },{ 11, 49 },{ 34, 22 },{ 66, 35 },{ 5, 72 },{ 31, 38 },
+ { 13, 8 },{ 58, 69 },{ 8, 28 },{ 24, 58 },{ 69, 11 },{ 52, 40 },{ 34, 9 },{ 73, 56 },
+ { 46, 23 },{ 43, 56 },{ 5, 37 },{ 19, 0 },{ 52, 4 },{ 76, 13 },{ 11, 66 },{ 58, 50 },
+ { 24, 46 },{ 25, 21 },{ 28, 71 },{ 73, 35 },{ 63, 64 },{ 44, 34 },{ 60, 10 },{ 13, 24 },
+ { 41, 66 },{ 3, 53 },{ 42, 14 },{ 69, 23 },{ 67, 78 },{ 34, 43 },{ 58, 41 },{ 30, 76 },
+ { 9, 41 },{ 4, 1 },{ 29, 31 },{ 15, 54 },{ 49, 57 },{ 61, 26 },{ 19, 5 },{ 56, 76 },
+ { 1, 71 },{ 74, 41 },{ 36, 57 },{ 50, 10 },{ 1, 20 },{ 23, 35 },{ 18, 15 },{ 70, 61 },
+ { 38, 5 },{ 30, 65 },{ 51, 27 },{ 59, 59 },{ 10, 61 },{ 31, 18 },{ 50, 49 },{ 76, 25 },
+ { 62, 3 },{ 18, 50 },{ 35, 29 },{ 2, 10 },{ 67, 43 },{ 45, 75 },{ 15, 72 },{ 57, 33 },
+ { 69, 70 },{ 17, 32 },{ 26, 4 },{ 4, 45 },{ 39, 42 },{ 75, 78 },{ 70, 17 },{ 28, 51 },
+ { 2, 62 },{ 48, 15 },{ 44, 63 },{ 11, 21 },{ 64, 52 },{ 34, 70 },{ 44, 25 },{ 8, 6 },
+ { 21, 63 },{ 75, 31 },{ 59, 20 },{ 24, 40 },{ 36, 11 },{ 55, 53 },{ 75, 48 },{ 47, 78 },
+ { 15, 1 },{ 44, 45 },{ 18, 27 },{ 64, 11 },{ 75, 65 },{ 13, 44 },{ 28, 14 },{ 55, 70 },
+ { 35, 36 },{ 62, 31 },{ 26, 60 },{ 12, 12 },{ 49, 37 },{ 7, 56 },{ 73, 6 },{ 40, 0 },
+ { 5, 31 },{ 39, 60 },{ 65, 73 },{ 51, 21 },{ 68, 51 },{ 23, 77 },{ 33, 49 },{ 27, 27 },
+ { 9, 74 },{ 56, 4 },{ 69, 39 },{ 40, 20 },{ 7, 19 },{ 56, 61 },{ 22, 54 },{ 70, 27 },
+ { 11, 36 },{ 7, 67 },{ 43, 70 },{ 24, 17 },{ 53, 43 },{ 76, 56 },{ 78, 6 },{ 48, 31 },
+ { 32, 6 },{ 62, 57 },{ 63, 15 },{ 15, 65 },{ 1, 35 },{ 43, 52 },{ 48, 6 },{ 74, 72 },
+ { 15, 42 },{ 38, 26 },{ 4, 24 },{ 26, 69 },{ 51, 66 },{ 61, 40 },{ 23, 9 },{ 67, 3 },
+ { 0, 45 },{ 26, 35 },{ 30, 56 },{ 54, 15 },{ 73, 15 },{ 18, 75 },{ 63, 67 },{ 32, 78 },
+ { 6, 51 },{ 42, 32 },{ 15, 17 },{ 68, 33 },{ 30, 44 },{ 59, 1 },{ 6, 77 },{ 49, 53 },
+ { 10, 30 },{ 38, 13 },{ 71, 54 },{ 57, 25 },{ 18, 61 },{ 32, 24 },{ 49, 71 },{ 4, 8 },
+ { 39, 49 },{ 63, 46 },{ 20, 47 },{ 3, 65 },{ 38, 70 },{ 20, 25 },{ 71, 20 },{ 55, 35 },
+ { 42, 7 },{ 69, 64 },{ 16, 8 },{ 46, 61 },{ 33, 33 },{ 71, 78 },{ 12, 57 },{ 4, 39 },
+ { 58, 9 },{ 31, 60 },{ 28, 2 },{ 2, 15 },{ 56, 47 },{ 45, 17 },{ 43, 39 },{ 13, 70 },
+ { 77, 34 },{ 18, 38 },{ 62, 74 },{ 28, 21 },{ 67, 26 },{ 1, 58 },{ 10, 2 },{ 53, 74 },
+ { 8, 48 },{ 21, 68 },{ 47, 44 },{ 70, 7 },{ 11, 25 },{ 39, 74 },{ 55, 56 },{ 35, 18 },
+ { 58, 30 },{ 2, 75 },{ 24, 43 },{ 37, 54 },{ 69, 47 },{ 62, 21 },{ 46, 2 },{ 23, 29 },
+ { 21, 14 },{ 67, 58 },{ 0, 27 },{ 37, 38 },{ 77, 68 },{ 21, 52 },{ 76, 10 },{ 35, 64 },
+ { 45, 11 },{ 65, 39 },{ 25, 75 },{ 0, 49 },{ 59, 64 },{ 9, 10 },{ 49, 27 },{ 30, 13 },
+ { 15, 34 },{ 56, 17 },{ 35, 46 },{ 24, 64 },{ 53, 0 },{ 52, 36 },{ 77, 18 },{ 12, 47 },
+ { 36, 3 },{ 48, 65 },{ 72, 68 },{ 38, 30 },{ 75, 44 },{ 12, 18 },{ 18, 3 },{ 65, 6 },
+ { 15, 60 },{ 58, 44 },{ 28, 40 },{ 47, 55 },{ 66, 19 },{ 4, 4 },{ 25, 6 },{ 3, 59 },
+ { 60, 71 },{ 6, 35 },{ 63, 34 },{ 40, 17 },{ 28, 48 },{ 31, 70 },{ 63, 60 },{ 53, 7 },
+ { 19, 21 },{ 75, 1 },{ 72, 31 },{ 41, 58 },{ 42, 28 },{ 12, 67 },{ 5, 22 },{ 61, 49 },
+ { 51, 18 },{ 8, 42 },{ 35, 77 },{ 75, 61 },{ 21, 59 },{ 26, 29 },{ 12, 0 },{ 45, 69 },
+ { 49, 42 },{ 59, 12 },{ 12, 53 },{ 77, 39 },{ 8, 15 },{ 53, 61 },{ 68, 73 },{ 31, 9 },
+ { 22, 34 },{ 63, 25 },{ 42, 47 },{ 7, 70 },{ 39, 24 },{ 15, 26 },{ 73, 52 },{ 28, 58 },
+ { 64, 78 },{ 42, 1 },{ 72, 12 },{ 21, 7 },{ 53, 30 },{ 34, 53 },{ 75, 27 },{ 22, 72 },
+ { 17, 46 },{ 57, 37 },{ 77, 74 },{ 33, 37 },{ 47, 13 },{ 59, 53 },{ 39, 65 },{ 15, 13 },
+ { 1, 52 },{ 60, 5 },{ 68, 41 },{ 25, 23 },{ 65, 65 },{ 40, 40 },{ 6, 29 },{ 28, 75 },
+ { 7, 62 },{ 49, 22 },{ 51, 74 },{ 74, 21 },{ 47, 50 },{ 14, 39 },{ 34, 13 },{ 26, 50 },
+ { 0, 3 },{ 67, 16 },{ 17, 68 },{ 56, 67 },{ 40, 9 },{ 70, 58 },{ 46, 33 },{ 29, 63 },
+ { 2, 42 },{ 31, 22 },{ 2, 18 },{ 16, 78 },{ 54, 50 },{ 12, 31 },{ 58, 76 },{ 55, 24 },
+ { 15, 56 },{ 34, 72 },{ 1, 12 },{ 71, 36 },{ 32, 29 },{ 50, 6 },{ 78, 66 },{ 50, 46 },
+ { 24, 15 },{ 20, 42 },{ 68, 9 },{ 41, 62 },{ 7, 1 },{ 3, 47 },{ 61, 29 },{ 17, 10 },
+ { 47, 73 },{ 66, 53 },{ 38, 35 },{ 2, 69 },{ 33, 45 },{ 9, 23 },{ 72, 44 },{ 29, 0 },
+ { 58, 15 },{ 71, 76 },{ 8, 55 },{ 52, 59 },{ 1, 32 },{ 44, 23 },{ 35, 56 },{ 38, 2 },
+ { 18, 34 },{ 11, 75 },{ 65, 70 },{ 62, 42 },{ 20, 18 },{ 19, 52 },{ 53, 12 },{ 66, 28 },
+ { 32, 66 },{ 51, 33 },{ 33, 16 },{ 28, 34 },{ 10, 6 },{ 41, 69 },{ 46, 58 },{ 72, 3 },
+ { 77, 60 },{ 8, 39 },{ 71, 24 },{ 23, 66 },{ 49, 1 },{ 44, 43 },{ 28, 7 },{ 57, 55 },
+ { 55, 40 },{ 2, 26 },{ 23, 57 },{ 42, 16 },{ 26, 41 },{ 4, 75 },{ 69, 68 },{ 14, 20 },
+ { 66, 12 },{ 66, 45 },{ 10, 58 },{ 37, 21 },{ 23, 2 },{ 53, 67 },{ 6, 10 },{ 71, 50 },
+ { 39, 52 },{ 61, 0 },{ 28, 26 },{ 9, 46 },{ 57, 22 },{ 19, 73 },{ 47, 36 },{ 75, 34 },
+ { 43, 76 },{ 63, 56 },{ 30, 50 },{ 75, 11 },{ 45, 8 },{ 17, 24 },{ 12, 64 },{ 59, 35 },
+ { 32, 40 },{ 62, 8 },{ 3, 56 },{ 44, 29 },{ 60, 68 },{ 26, 12 },{ 77, 23 },{ 78, 78 },
+ { 17, 41 },{ 29, 67 },{ 33, 2 },{ 36, 32 },{ 48, 63 },{ 77, 46 },{ 68, 21 },{ 11, 71 },
+ { 7, 32 },{ 38, 59 },{ 71, 63 },{ 53, 3 },{ 23, 32 },{ 11, 15 },{ 54, 20 },{ 52, 47 },
+ { 16, 51 },{ 13, 7 },{ 36, 8 },{ 59, 47 },{ 65, 36 },{ 24, 48 },{ 69, 1 },{ 54, 72 },
+ { 38, 44 },{ 46, 19 },{ 76, 70 },{ 78, 37 },{ 23, 74 },{ 76, 15 },{ 6, 64 },{ 29, 17 },
+ { 45, 52 },{ 69, 32 },{ 40, 75 },{ 9, 51 },{ 22, 26 },{ 57, 59 },{ 49, 11 },{ 77, 53 },
+ { 61, 19 },{ 21, 11 },{ 26, 63 },{ 11, 28 },{ 46, 39 },{ 78, 5 },{ 17, 58 },{ 37, 69 },
+ { 41, 26 },{ 13, 37 },{ 64, 62 },{ 6, 14 },{ 55, 5 },{ 18, 77 },{ 21, 37 },{ 63, 49 },
+ { 32, 54 },{ 58, 27 },{ 65, 75 },{ 43, 3 },{ 74, 42 },{ 30, 36 },{ 45, 66 },{ 71, 14 },
+ { 2, 73 },{ 36, 24 },{ 78, 30 },{ 53, 54 },{ 6, 44 },{ 21, 2 },{ 40, 14 },{ 71, 57 },
+ { 42, 36 },{ 51, 25 },{ 16, 71 },{ 3, 20 },{ 58, 73 },{ 25, 53 },{ 7, 5 },{ 59, 38 },
+ { 42, 54 },{ 33, 7 },{ 65, 17 },{ 5, 60 },{ 26, 20 },{ 56, 11 },{ 31, 73 },{ 22, 45 },
+ { 68, 5 },{ 74, 62 },{ 8, 25 },{ 35, 59 },{ 17, 17 },{ 70, 41 },{ 38, 47 },{ 19, 66 },
+ { 61, 65 },{ 47, 28 },{ 74, 76 },{ 17, 30 },{ 4, 49 },{ 51, 0 },{ 71, 30 },{ 50, 69 },
+ { 13, 2 },{ 51, 42 },{ 30, 30 },{ 15, 48 },{ 68, 55 },{ 27, 5 },{ 64, 2 },{ 8, 72 },
+ { 60, 32 },{ 35, 40 },{ 37, 16 },{ 37, 78 },{ 9, 37 },{ 1, 9 },{ 21, 56 },{ 65, 22 },
+ { 36, 63 },{ 50, 57 },{ 1, 64 },{ 2, 38 },{ 56, 43 },{ 51, 14 },{ 19, 13 },{ 25, 70 },
+ { 40, 6 },{ 78, 20 },{ 67, 66 },{ 12, 43 },{ 21, 22 },{ 62, 12 },{ 29, 42 },{ 50, 51 },
+ { 14, 10 },{ 40, 31 },{ 14, 62 },{ 67, 49 },{ 3, 2 },{ 43, 65 },{ 64, 29 },{ 78, 56 },
+ { 43, 21 },{ 30, 60 },{ 58, 3 },{ 5, 27 },{ 46, 76 },{ 74, 47 },{ 74, 8 },{ 49, 33 },
+ { 29, 10 },{ 9, 68 },{ 21, 31 },{ 41, 44 },{ 62, 70 },{ 30, 25 },{ 67, 38 },{ 10, 19 },
+ { 49, 61 },{ 27, 77 },{ 74, 67 },{ 26, 45 },{ 53, 19 },{ 14, 55 },{ 60, 56 },{ 72, 16 },
+ { 44, 12 },{ 35, 50 },{ 74, 26 },{ 18, 7 },{ 33, 68 },{ 14, 29 },{ 70, 72 },{ 54, 37 },
+ { 14, 76 },{ 4, 41 },{ 53, 64 },{ 32, 21 },{ 48, 8 },{ 5, 52 },{ 56, 31 },{ 76, 3 },
+ { 20, 62 },{ 56, 77 },{ 35, 75 },{ 48, 48 },{ 6, 17 },{ 30, 53 },{ 73, 37 },{ 26, 38 },
+ { 34, 28 },{ 59, 17 },{ 60, 43 },{ 5, 69 },{ 67, 61 },{ 23, 16 },{ 11, 33 },{ 43, 72 },
+ { 30, 4 },{ 41, 56 },{ 9, 3 },{ 60, 25 },{ 70, 10 },{ 21, 50 },{ 77, 50 },{ 39, 36 },
+ { 63, 5 },{ 9, 60 },{ 62, 51 },{ 23, 70 },{ 69, 25 },{ 41, 19 },{ 20, 39 },{ 11, 11 },
+ { 44, 60 },{ 75, 58 },{ 48, 25 },{ 1, 0 },{ 32, 11 },{ 45, 4 },{ 13, 23 },{ 64, 43 },
+ { 60, 74 },{ 2, 33 },{ 32, 46 },{ 24, 61 },{ 60, 60 },{ 48, 40 },{ 22, 4 },{ 78, 71 },
+ { 13, 49 },{ 2, 22 },{ 25, 25 },{ 38, 10 },{ 56, 8 },{ 76, 41 },{ 46, 68 },{ 43, 48 },
+ { 8, 75 },{ 62, 35 },{ 74, 19 },{ 20, 76 },{ 18, 44 },{ 44, 32 },{ 38, 72 },{ 73, 0 },
+ { 56, 49 },{ 27, 32 },{ 48, 16 },{ 6, 58 },{ 55, 68 },{ 5, 11 },{ 28, 65 },{ 71, 47 },
+ { 64, 18 },{ 14, 67 },{ 8, 34 },{ 49, 76 },{ 52, 29 },{ 67, 77 },{ 32, 32 },{ 26, 54 },
+ { 13, 14 },{ 30, 16 },{ 70, 65 },{ 38, 41 },{ 76, 32 },{ 17, 35 },{ 52, 9 },{ 54, 57 },
+ { 25, 9 },{ 77, 64 },{ 78, 12 },{ 34, 0 },{ 10, 43 },{ 33, 58 },{ 57, 19 },{ 52, 44 },
+ { 17, 4 },{ 70, 54 },{ 18, 25 },{ 64, 27 },{ 54, 75 },{ 2, 45 },{ 16, 63 },{ 42, 51 },
+ { 36, 26 },{ 66, 11 },{ 17, 55 },{ 30, 71 },{ 64, 59 },{ 5, 7 },{ 73, 25 },{ 13, 74 },
+ { 40, 64 },{ 45, 38 },{ 73, 73 },{ 23, 19 },{ 68, 35 },{ 45, 1 },{ 44, 15 },{ 32, 42 },
+ { 8, 52 },{ 52, 22 },{ 56, 63 },{ 6, 20 },{ 25, 78 },{ 24, 28 },{ 66, 6 },{ 4, 65 },
+ { 52, 39 },{ 2, 29 },{ 33, 62 },{ 22, 40 },{ 62, 47 },{ 37, 7 },{ 56, 1 },{ 48, 54 },
+ { 1, 50 },{ 35, 22 },{ 5, 78 },{ 18, 18 },{ 66, 69 },{ 18, 49 },{ 63, 14 },{ 0, 17 },
+ { 33, 51 },{ 73, 40 },{ 42, 77 },{ 35, 34 },{ 14, 5 },{ 73, 59 },{ 43, 26 },{ 7, 37 },
+ { 28, 74 },{ 72, 5 },{ 56, 28 },{ 50, 71 },{ 25, 57 },{ 65, 34 },{ 0, 74 },{ 39, 57 },
+ { 13, 40 },{ 43, 9 },{ 63, 53 },{ 29, 19 },{ 18, 67 },{ 60, 9 },{ 10, 22 },{ 44, 42 },
+ { 58, 66 },{ 69, 29 },{ 9, 63 },{ 50, 19 },{ 52, 51 },{ 19, 28 },{ 30, 1 },{ 29, 45 },
+ { 69, 74 },{ 68, 47 },{ 9, 9 },{ 36, 67 },{ 1, 61 },{ 76, 22 },{ 27, 14 },{ 47, 30 },
+ { 11, 47 },{ 49, 5 },{ 25, 34 },{ 49, 64 },{ 77, 8 },{ 78, 40 },{ 62, 39 },{ 25, 66 },
+ { 36, 45 },{ 63, 0 },{ 16, 1 },{ 37, 14 },{ 63, 23 },{ 75, 53 },{ 19, 59 },{ 7, 25 },
+ { 22, 10 },{ 53, 32 },{ 56, 53 },{ 69, 18 },{ 40, 73 },{ 11, 78 },{ 39, 33 },{ 23, 51 },
+ { 4, 36 },{ 59, 70 },{ 55, 13 },{ 34, 5 },{ 16, 38 },{ 45, 46 },{ 11, 70 },{ 75, 72 },
+ { 38, 22 },{ 4, 55 },{ 2, 13 },{ 16, 23 },{ 44, 62 },{ 65, 57 },{ 28, 37 },{ 55, 41 },
+ { 21, 71 },{ 69, 13 },{ 39, 1 },{ 74, 32 },{ 46, 21 },{ 13, 52 },{ 51, 78 },{ 40, 49 },
+ { 68, 0 },{ 16, 13 },{ 6, 45 },{ 31, 63 },{ 2, 66 },{ 65, 44 },{ 13, 31 },{ 60, 6 },
+ { 50, 36 },{ 28, 23 },{ 55, 60 },{ 3, 5 },{ 25, 3 },{ 34, 38 },{ 68, 62 },{ 55, 23 },
+ { 11, 61 },{ 78, 27 },{ 40, 69 },{ 21, 44 },{ 51, 11 },{ 31, 55 },{ 10, 16 },{ 69, 51 },
+ { 33, 13 },{ 5, 76 },{ 47, 56 },{ 68, 23 },{ 39, 29 },{ 32, 75 },{ 72, 69 },{ 76, 36 },
+ { 59, 76 },{ 58, 48 },{ 22, 0 },{ 9, 29 },{ 58, 31 },{ 75, 16 },{ 22, 60 },{ 46, 71 },
+ { 31, 28 },{ 78, 52 },{ 41, 41 },{ 40, 11 },{ 75, 2 },{ 15, 45 },{ 60, 63 },{ 61, 14 },
+ { 18, 10 },{ 27, 50 },{ 71, 42 },{ 22, 23 },{ 16, 70 },{ 47, 3 },{ 40, 59 },{ 58, 38 },
+ { 63, 72 },{ 11, 57 },{ 42, 18 },{ 4, 31 },{ 11, 4 },{ 49, 47 },{ 55, 16 },{ 27, 71 },
+ { 77, 59 },{ 26, 17 },{ 25, 40 },{ 7, 13 },{ 71, 9 },{ 1, 43 },{ 43, 35 },{ 50, 66 },
+ { 66, 30 },{ 6, 70 },{ 37, 53 },{ 20, 33 },{ 60, 52 },{ 60, 21 },{ 27, 8 },{ 0, 77 },
+ { 54, 4 },{ 6, 48 },{ 39, 4 },{ 15, 20 },{ 27, 61 },{ 71, 60 },{ 53, 26 },{ 33, 19 },
+ { 70, 36 },{ 51, 58 },{ 20, 56 },{ 66, 74 },{ 35, 72 },{ 12, 26 },{ 32, 35 },{ 9, 66 },
+ { 72, 21 },{ 74, 49 },{ 53, 72 },{ 35, 47 },{ 46, 13 },{ 15, 77 },{ 10, 38 },{ 3, 17 },
+ { 53, 48 },{ 69, 4 },{ 49, 29 },{ 37, 64 },{ 27, 30 },{ 74, 65 },{ 62, 33 },{ 17, 48 },
+ { 21, 6 },{ 42, 23 },{ 1, 8 },{ 43, 55 },{ 64, 65 },{ 7, 54 },{ 64, 8 },{ 22, 65 },
+ { 66, 41 },{ 33, 10 },{ 1, 24 },{ 25, 46 },{ 44, 77 },{ 49, 39 },{ 3, 73 },{ 14, 36 },
+ { 59, 58 },{ 24, 76 },{ 50, 15 },{ 71, 27 },{ 19, 16 },{ 59, 2 },{ 36, 31 },{ 67, 54 },
+ { 30, 57 },{ 7, 41 },{ 46, 51 },{ 7, 0 },{ 44, 68 },{ 70, 15 },{ 37, 19 },{ 78, 46 },
+ { 13, 64 },{ 57, 44 },{ 31, 3 },{ 16, 28 },{ 60, 24 },{ 75, 76 },{ 30, 39 },{ 56, 73 },
+ { 32, 69 },{ 15, 7 },{ 2, 58 },{ 40, 39 },{ 7, 22 },{ 43, 6 },{ 16, 57 },{ 55, 34 },
+ { 57, 9 },{ 5, 34 },{ 52, 63 },{ 24, 13 },{ 75, 6 },{ 72, 55 },{ 29, 48 },{ 33, 25 },
+ { 18, 74 },{ 72, 33 },{ 67, 71 },{ 48, 22 },{ 22, 30 },{ 10, 50 },{ 61, 45 },{ 36, 77 },
+ { 78, 14 },{ 42, 63 },{ 0, 67 },{ 64, 21 },{ 48, 44 },{ 14, 15 },{ 50, 74 },{ 16, 43 },
+ { 28, 68 },{ 45, 34 },{ 50, 7 },{ 69, 44 },{ 6, 5 },{ 38, 50 },{ 1, 37 },{ 66, 2 },
+ { 23, 54 },{ 39, 15 },{ 57, 57 },{ 14, 72 },{ 19, 23 },{ 5, 63 },{ 77, 25 },{ 41, 29 },
+ { 59, 68 },{ 20, 1 },{ 23, 36 },{ 63, 16 },{ 36, 58 },{ 62, 29 },{ 30, 11 },{ 35, 42 },
+ { 68, 66 },{ 19, 63 },{ 74, 11 },{ 48, 1 },{ 72, 50 },{ 10, 12 },{ 4, 28 },{ 51, 53 },
+ { 29, 78 },{ 50, 24 },{ 22, 48 },{ 27, 20 },{ 64, 38 },{ 72, 78 },{ 0, 55 },{ 42, 74 },
+ { 47, 60 },{ 15, 33 },{ 8, 73 },{ 54, 11 },{ 75, 39 },{ 37, 37 },{ 63, 61 },{ 35, 3 },
+ { 12, 45 },{ 12, 20 },{ 53, 36 },{ 33, 66 },{ 67, 10 },{ 1, 70 },{ 29, 29 },{ 45, 18 },
+ { 59, 78 },{ 11, 53 },{ 24, 6 },{ 64, 49 },{ 66, 26 },{ 29, 53 },{ 43, 46 },{ 7, 9 },
+ { 20, 68 },{ 77, 30 },{ 34, 16 },{ 76, 63 },{ 54, 69 },{ 56, 25 },{ 19, 38 },{ 55, 46 },
+ { 1, 3 },{ 47, 9 },{ 3, 48 },{ 38, 66 },{ 71, 19 },{ 27, 42 },{ 14, 59 },{ 26, 25 },
+ { 54, 78 },{ 45, 27 },{ 7, 18 },{ 24, 73 },{ 68, 58 },{ 9, 31 },{ 59, 41 },{ 41, 53 },
+ { 58, 16 },{ 70, 75 },{ 12, 6 },{ 41, 7 },{ 27, 58 },{ 73, 45 },{ 48, 67 },{ 22, 18 },
+ { 6, 39 },{ 51, 31 },{ 8, 59 },{ 62, 4 },{ 10, 76 },{ 43, 40 },{ 77, 19 },{ 62, 55 },
+ { 39, 25 },{ 31, 76 },{ 17, 53 },{ 69, 34 },{ 19, 8 },{ 71, 67 },{ 32, 49 },{ 41, 0 },
+ { 14, 25 },{ 57, 62 },{ 34, 32 },{ 65, 13 },{ 45, 58 },{ 4, 68 },{ 42, 13 },{ 11, 41 },
+ { 77, 0 },{ 60, 36 },{ 25, 62 },{ 4, 14 },{ 30, 7 },{ 23, 43 },{ 54, 18 },{ 62, 75 },
+ { 0, 33 },{ 45, 49 },{ 4, 53 },{ 25, 32 },{ 54, 54 },{ 39, 71 },{ 57, 6 },{ 13, 69 },
+ { 4, 23 },{ 66, 51 },{ 20, 13 },{ 34, 56 },{ 47, 37 },{ 69, 21 },{ 75, 57 },{ 31, 20 },
+ { 14, 1 },{ 48, 73 },{ 77, 42 },{ 70, 6 },{ 31, 44 },{ 60, 27 },{ 20, 73 },{ 62, 67 },
+ { 35, 9 },{ 18, 31 },{ 77, 11 },{ 41, 33 },{ 37, 61 },{ 67, 40 },{ 4, 61 },{ 49, 19 },
+ { 19, 47 },{ 2, 76 },{ 53, 41 },{ 27, 2 },{ 72, 29 },{ 52, 3 },{ 20, 21 },{ 16, 65 },
+ { 39, 46 },{ 58, 51 },{ 72, 71 },{ 10, 34 },{ 40, 21 },{ 59, 11 },{ 78, 48 },{ 31, 62 },
+ { 54, 65 },{ 14, 9 },{ 34, 27 },{ 38, 76 },{ 0, 21 },{ 8, 49 },{ 4, 3 },{ 58, 33 },
+ { 26, 68 },{ 65, 63 },{ 29, 13 },{ 28, 35 },{ 60, 18 },{ 25, 51 },{ 51, 49 },{ 3, 41 },
+ { 48, 11 },{ 76, 69 },{ 73, 13 },{ 45, 64 },{ 21, 27 },{ 19, 3 },{ 66, 32 },{ 8, 65 },
+ { 64, 77 },{ 17, 40 },{ 48, 32 },{ 47, 77 },{ 7, 28 },{ 66, 46 },{ 17, 61 },{ 38, 6 },
+ { 37, 43 },{ 8, 16 },{ 53, 59 },{ 74, 3 },{ 46, 24 },{ 26, 74 },{ 73, 53 },{ 71, 39 },
+ { 16, 17 },{ 39, 55 },{ 57, 71 },{ 67, 24 },{ 13, 55 },{ 35, 17 },{ 9, 0 },{ 47, 42 },
+ { 42, 70 },{ 56, 21 },{ 21, 53 },{ 71, 62 },{ 25, 22 },{ 75, 24 },{ 27, 39 },{ 67, 8 },
+ { 33, 73 },{ 77, 35 },{ 25, 11 },{ 61, 57 },{ 9, 69 },{ 53, 6 },{ 9, 44 },{ 34, 52 },
+ { 3, 8 },{ 37, 28 },{ 59, 43 },{ 0, 60 },{ 45, 15 },{ 27, 64 },{ 10, 27 },{ 64, 70 },
+ { 22, 77 },{ 55, 29 },{ 19, 36 },{ 50, 61 },{ 68, 16 },{ 44, 3 },{ 77, 75 },{ 2, 51 },
+ { 36, 36 },{ 1, 16 },{ 44, 53 },{ 32, 5 },{ 56, 38 },{ 61, 1 },{ 13, 13 },{ 14, 50 },
+ { 70, 49 },{ 51, 70 },{ 31, 25 },{ 12, 74 },{ 3, 32 },{ 53, 15 },{ 35, 68 },{ 51, 44 },
+ { 28, 55 },{ 70, 2 },{ 43, 30 },{ 14, 30 },{ 7, 57 },{ 69, 28 },{ 37, 11 },{ 23, 69 },
+ { 69, 59 },{ 19, 42 },{ 52, 76 },{ 17, 6 },{ 55, 50 },{ 30, 33 },{ 62, 11 },{ 9, 20 },
+ { 76, 44 },{ 42, 60 },{ 4, 72 },{ 25, 16 },{ 51, 28 },{ 58, 64 },{ 22, 59 },{ 78, 7 },
+ { 63, 42 },{ 33, 1 },{ 30, 47 },{ 3, 26 },{ 73, 66 },{ 44, 8 },{ 12, 38 },{ 41, 37 },
+ { 66, 20 },{ 17, 77 },{ 40, 67 },{ 67, 37 },{ 12, 61 },{ 25, 28 },{ 55, 2 },{ 65, 55 },
+ { 36, 20 },{ 74, 17 },{ 37, 48 },{ 4, 46 },{ 8, 3 },{ 68, 72 },{ 50, 54 },{ 61, 30 },
+ { 16, 21 },{ 29, 72 },{ 34, 60 },{ 52, 21 },{ 1, 63 },{ 23, 41 },{ 25, 7 },{ 74, 36 },
+ { 45, 74 },{ 64, 3 },{ 51, 38 },{ 16, 68 },{ 76, 55 },{ 31, 15 },{ 34, 40 },{ 75, 28 },
+ { 57, 13 },{ 10, 7 },{ 61, 48 },{ 19, 51 },{ 44, 24 },{ 61, 72 },{ 37, 2 },{ 3, 38 },
+ { 2, 11 },{ 42, 44 },{ 73, 77 },{ 17, 27 },{ 48, 57 },{ 22, 63 },{ 22, 14 },{ 62, 25 },
+ { 47, 69 },{ 14, 46 },{ 47, 17 },{ 61, 61 },{ 6, 67 },{ 70, 46 },{ 73, 9 },{ 31, 31 },
+ { 46, 5 },{ 29, 60 },{ 5, 21 },{ 24, 0 },{ 46, 48 },{ 9, 55 },{ 52, 33 },{ 2, 0 },
+ { 7, 33 },{ 26, 44 },{ 66, 67 },{ 41, 10 },{ 17, 12 },{ 57, 54 },{ 59, 8 },{ 30, 22 },
+ { 72, 23 },{ 36, 73 },{ 5, 50 },{ 76, 72 },{ 62, 36 },{ 21, 34 },{ 18, 70 },{ 52, 67 },
+ { 31, 52 },{ 58, 20 },{ 12, 17 },{ 45, 41 },{ 69, 56 },{ 39, 23 },{ 57, 78 },{ 18, 56 },
+ { 70, 32 },{ 13, 78 },{ 39, 63 },{ 13, 35 },{ 68, 12 },{ 29, 4 },{ 76, 50 },{ 31, 37 },
+ { 51, 10 },{ 11, 65 },{ 48, 26 },{ 40, 51 },{ 78, 4 },{ 20, 24 },{ 30, 66 },{ 0, 40 },
+ { 54, 45 },{ 78, 65 },{ 41, 16 },{ 8, 13 },{ 43, 0 },{ 1, 27 },{ 54, 62 },{ 67, 76 },
+ { 25, 48 },{ 68, 43 },{ 38, 33 },{ 6, 74 },{ 58, 26 },{ 15, 41 },{ 21, 8 },{ 2, 56 },
+ { 66, 16 },{ 44, 57 },{ 28, 17 },{ 61, 53 },{ 50, 3 },{ 11, 24 },{ 21, 75 },{ 47, 35 },
+ { 73, 60 },{ 55, 75 },{ 24, 56 },{ 75, 21 },{ 33, 43 },{ 6, 43 },{ 35, 13 },{ 64, 32 },
+ { 34, 64 },{ 15, 3 },{ 67, 4 },{ 62, 64 },{ 23, 26 },{ 34, 75 },{ 56, 42 },{ 4, 18 },
+ { 52, 13 },{ 13, 58 },{ 24, 37 },{ 47, 63 },{ 69, 69 },{ 42, 27 },{ 74, 43 },{ 5, 1 },
+ { 63, 19 },{ 20, 65 },{ 32, 8 },{ 49, 50 },{ 0, 30 },{ 16, 52 },{ 44, 71 },{ 61, 6 },
+ { 56, 35 },{ 18, 19 },{ 6, 60 },{ 36, 54 },{ 76, 14 },{ 65, 52 },{ 35, 24 },{ 9, 40 },
+ { 28, 78 },{ 1, 72 },{ 40, 42 },{ 41, 3 },{ 12, 10 },{ 57, 69 },{ 17, 33 },{ 52, 24 },
+ { 72, 74 },{ 69, 38 },{ 21, 46 },{ 52, 56 },{ 10, 72 },{ 43, 12 },{ 1, 46 },{ 29, 26 },
+ { 75, 7 },{ 24, 67 },{ 45, 31 },{ 65, 27 },{ 38, 58 },{ 12, 29 },{ 70, 52 },{ 23, 4 },
+ { 50, 78 },{ 6, 7 },{ 61, 41 },{ 30, 41 },{ 60, 14 },{ 75, 64 },{ 42, 66 },{ 25, 19 },
+ { 11, 48 },{ 45, 20 },{ 73, 34 },{ 16, 74 },{ 62, 77 },{ 47, 45 },{ 6, 25 },{ 25, 60 },
+ { 64, 58 },{ 37, 0 },{ 72, 17 },{ 35, 30 },{ 78, 57 },{ 33, 48 },{ 28, 10 },{ 64, 10 },
+ { 6, 36 },{ 59, 46 },{ 14, 63 },{ 54, 8 },{ 35, 70 },{ 55, 31 },{ 17, 15 },{ 72, 2 },
+ { 24, 34 },{ 67, 63 },{ 38, 18 },{ 31, 58 },{ 11, 2 },{ 1, 19 },{ 52, 73 },{ 9, 53 },
+ { 38, 38 },{ 57, 60 },{ 70, 25 },{ 75, 47 },{ 26, 72 },{ 50, 16 },{ 2, 68 },{ 20, 29 },
+ { 42, 50 },{ 35, 6 },{ 13, 22 },{ 59, 23 },{ 19, 45 },{ 47, 66 },{ 64, 46 },{ 5, 10 },
+ { 50, 41 },{ 65, 0 },{ 8, 62 },{ 27, 53 },{ 0, 35 },{ 32, 18 },{ 19, 78 },{ 58, 74 },
+ { 42, 35 },{ 53, 52 },{ 78, 1 },{ 41, 75 },{ 11, 32 },{ 47, 7 },{ 0, 53 },{ 59, 31 },
+ { 23, 11 },{ 20, 59 },{ 74, 29 },{ 75, 68 },{ 8, 46 },{ 71, 10 },{ 33, 36 },{ 45, 61 },
+ { 7, 77 },{ 50, 21 },{ 30, 70 },{ 60, 66 },{ 16, 36 },{ 5, 15 },{ 39, 8 },{ 50, 35 },
+ { 27, 46 },{ 72, 39 },{ 13, 67 },{ 57, 4 },{ 27, 23 },{ 60, 51 },{ 16, 9 },{ 64, 24 },
+ { 36, 50 },{ 73, 57 },{ 32, 77 },{ 42, 21 },{ 6, 30 },{ 65, 72 },{ 45, 54 },{ 78, 24 },
+ { 13, 43 },{ 57, 17 },{ 22, 70 },{ 27, 31 },{ 47, 0 },{ 64, 39 },{ 69, 7 },{ 4, 58 },
+ { 27, 6 },{ 36, 62 },{ 40, 27 },{ 56, 56 },{ 0, 10 },{ 20, 54 },{ 21, 17 },{ 2, 43 },
+ { 7, 71 },{ 44, 38 },{ 48, 70 },{ 67, 18 },{ 66, 48 },{ 11, 18 },{ 48, 14 },{ 22, 39 },
+ { 71, 70 },{ 18, 2 },{ 41, 47 },{ 54, 28 },{ 29, 64 },{ 77, 77 },{ 67, 33 },{ 16, 60 },
+ { 39, 13 },{ 50, 64 },{ 15, 25 },{ 66, 59 },{ 29, 50 },{ 57, 39 },{ 52, 1 },{ 33, 22 },
+ { 76, 38 },{ 9, 11 },{ 26, 1 },{ 70, 78 },{ 16, 49 },{ 51, 46 },{ 56, 12 },{ 76, 61 },
+ { 38, 68 },{ 76, 16 },{ 36, 40 },{ 14, 71 },{ 26, 13 },{ 73, 51 },{ 55, 71 },{ 46, 28 },
+ { 5, 40 },{ 12, 4 },{ 40, 56 },{ 70, 22 },{ 26, 36 },{ 40, 78 },{ 64, 5 },{ 5, 53 },
+ { 9, 24 },{ 5, 66 },{ 61, 34 },{ 63, 68 },{ 45, 10 },{ 24, 49 },{ 37, 30 },{ 2, 6 },
+ { 56, 48 },{ 30, 74 },{ 22, 21 },{ 77, 32 },{ 33, 57 },{ 61, 16 },{ 17, 64 },{ 71, 44 },
+ { 32, 14 },{ 50, 59 },{ 70, 64 },{ 15, 39 },{ 53, 22 },{ 1, 75 },{ 34, 45 },{ 46, 75 },
+ { 2, 21 },{ 20, 5 },{ 12, 54 },{ 53, 39 },{ 24, 30 },{ 67, 29 },{ 58, 0 },{ 36, 4 },
+ { 72, 13 },{ 47, 52 },{ 25, 65 },{ 8, 35 },{ 59, 60 },{ 32, 28 },{ 13, 76 },{ 0, 48 },
+ { 49, 8 },{ 49, 31 },{ 73, 5 },{ 21, 43 },{ 41, 61 },{ 3, 62 },{ 15, 18 },{ 38, 16 },
+ { 67, 52 },{ 62, 9 },{ 46, 44 },{ 26, 55 },{ 20, 11 },{ 57, 67 },{ 76, 27 },{ 38, 74 },
+ { 78, 70 },{ 57, 27 },{ 29, 38 },{ 19, 71 },{ 3, 36 },{ 8, 5 },{ 63, 43 },{ 43, 18 },
+ { 11, 50 },{ 66, 75 },{ 13, 27 },{ 35, 65 },{ 42, 33 },{ 0, 15 },{ 52, 5 },{ 9, 58 },
+ { 58, 55 },{ 24, 24 },{ 62, 20 },{ 32, 0 },{ 39, 43 },{ 74, 54 },{ 3, 78 },{ 35, 11 },
+ { 69, 40 },{ 19, 32 },{ 43, 68 },{ 52, 18 },{ 22, 57 },{ 60, 75 },{ 9, 14 },{ 58, 35 },
+ { 10, 68 },{ 28, 43 },{ 73, 26 },{ 66, 64 },{ 23, 75 },{ 7, 47 },{ 36, 23 },{ 52, 61 },
+ { 66, 14 },{ 24, 9 },{ 53, 47 },{ 74, 74 },{ 42, 5 },{ 35, 55 },{ 5, 26 },{ 17, 47 },
+ { 47, 25 },{ 73, 47 },{ 76, 4 },{ 31, 67 },{ 34, 35 },{ 58, 7 },{ 14, 11 },{ 63, 50 },
+ { 11, 37 },{ 49, 72 },{ 29, 20 },{ 71, 31 },{ 43, 59 },{ 8, 76 },{ 49, 38 },{ 73, 62 },
+ { 16, 54 },{ 74, 20 },{ 68, 1 },{ 21, 67 },{ 30, 6 },{ 78, 43 },{ 41, 25 },{ 48, 49 },
+ { 15, 31 },{ 62, 71 },{ 64, 36 },{ 32, 60 },{ 4, 13 },{ 50, 12 },{ 18, 76 },{ 28, 27 },
+ { 0, 66 },{ 41, 71 },{ 38, 46 },{ 2, 31 },{ 61, 23 },{ 6, 56 },{ 48, 2 },{ 62, 58 },
+ { 19, 20 },{ 23, 45 },{ 24, 2 },{ 53, 34 },{ 64, 12 },{ 53, 65 },{ 11, 63 },{ 28, 15 },
+ { 42, 39 },{ 76, 9 },{ 67, 45 },{ 20, 37 },{ 7, 23 },{ 28, 59 },{ 47, 20 },{ 68, 68 },
+ { 53, 77 },{ 29, 76 },{ 78, 51 },{ 11, 9 },{ 46, 55 },{ 63, 27 },{ 7, 42 },{ 38, 9 },
+ { 32, 51 },{ 4, 74 },{ 32, 33 },{ 61, 3 },{ 57, 46 },{ 75, 35 },{ 16, 4 },{ 19, 61 },
+ { 50, 27 },{ 70, 57 },{ 34, 71 },{ 55, 15 },{ 18, 26 },{ 70, 16 },{ 14, 42 },{ 44, 75 },
+ { 53, 55 },{ 4, 5 },{ 39, 31 },{ 2, 59 },{ 60, 40 },{ 23, 52 },{ 19, 15 },{ 35, 15 },
+ { 74, 71 },{ 42, 64 },{ 0, 23 },{ 15, 73 },{ 31, 40 },{ 52, 69 },{ 68, 6 },{ 38, 52 },
+ { 78, 38 },{ 39, 20 },{ 59, 29 },{ 27, 67 },{ 8, 19 },{ 67, 55 },{ 42, 2 },{ 11, 45 },
+ { 48, 43 },{ 11, 0 },{ 23, 33 },{ 56, 10 },{ 7, 64 },{ 68, 26 },{ 59, 62 },{ 29, 8 },
+ { 9, 32 },{ 45, 35 },{ 71, 75 },{ 2, 49 },{ 35, 0 },{ 23, 62 },{ 57, 21 },{ 72, 41 },
+ { 0, 12 },{ 31, 46 },{ 45, 13 },{ 59, 50 },{ 23, 20 },{ 15, 57 },{ 48, 62 },{ 72, 65 },
+ { 56, 2 },{ 12, 15 },{ 44, 50 },{ 36, 27 },{ 25, 71 },{ 66, 34 },{ 2, 2 },{ 20, 50 },
+ { 68, 20 },{ 59, 71 },{ 29, 32 },{ 5, 33 },{ 21, 4 },{ 54, 43 },{ 3, 69 },{ 45, 6 },
+ { 77, 54 },{ 38, 60 },{ 15, 23 },{ 54, 26 },{ 72, 8 },{ 25, 41 },{ 15, 66 },{ 30, 18 },
+ { 68, 50 },{ 51, 75 },{ 42, 42 },{ 4, 44 },{ 37, 70 },{ 74, 78 },{ 0, 28 },{ 45, 23 },
+ { 64, 61 },{ 11, 73 },{ 61, 12 },{ 29, 56 },{ 34, 7 },{ 18, 35 },{ 76, 18 },{ 55, 52 },
+ { 37, 35 },{ 19, 10 },{ 10, 56 },{ 63, 74 },{ 71, 37 },{ 46, 67 },{ 47, 32 },{ 7, 8 },
+ { 78, 63 },{ 41, 14 },{ 22, 27 },{ 63, 31 },{ 26, 75 },{ 14, 52 },{ 56, 65 },{ 35, 48 },
+ { 65, 8 },{ 8, 27 },{ 25, 14 },{ 55, 19 },{ 32, 65 },{ 60, 38 },{ 19, 41 },{ 39, 77 },
+ { 7, 2 },{ 50, 56 },{ 7, 51 },{ 33, 24 },{ 69, 71 },{ 74, 14 },{ 71, 48 },{ 19, 69 },
+ { 51, 6 },{ 12, 34 },{ 43, 45 },{ 28, 3 },{ 66, 22 },{ 72, 59 },{ 5, 17 },{ 28, 49 },
+ { 54, 38 },{ 17, 1 },{ 63, 2 },{ 2, 40 },{ 49, 17 },{ 42, 56 },{ 8, 69 },{ 74, 31 },
+ { 35, 38 },{ 32, 12 },{ 61, 54 },{ 46, 73 },{ 13, 20 },{ 19, 57 },{ 44, 28 },{ 77, 73 },
+ { 64, 67 },{ 27, 25 },{ 63, 45 },{ 28, 62 },{ 40, 5 },{ 11, 40 },{ 0, 6 },{ 3, 54 },
+ { 57, 30 },{ 53, 9 },{ 16, 14 },{ 46, 59 },{ 74, 23 },{ 20, 48 },{ 56, 75 },{ 11, 60 },
+ { 50, 45 },{ 35, 19 },{ 21, 0 },{ 76, 46 },{ 69, 12 },{ 26, 34 },{ 32, 71 },{ 3, 24 },
+ { 55, 58 },{ 71, 1 },{ 66, 38 },{ 37, 55 },{ 13, 6 },{ 43, 10 },{ 3, 64 },{ 51, 34 },
+ { 15, 29 },{ 69, 61 },{ 36, 44 },{ 59, 18 },{ 45, 0 },{ 15, 69 },{ 1, 34 },{ 41, 30 },
+ { 49, 68 },{ 16, 44 },{ 27, 11 },{ 59, 5 },{ 68, 30 },{ 25, 58 },{ 6, 78 },{ 77, 58 },
+ { 33, 3 },{ 46, 40 },{ 21, 23 },{ 38, 65 },{ 3, 10 },{ 49, 23 },{ 60, 47 },{ 23, 38 },
+ { 69, 77 },{ 6, 38 },{ 64, 16 },{ 29, 69 },{ 61, 68 },{ 33, 29 },{ 49, 52 },{ 68, 42 },
+ { 22, 7 },{ 15, 61 },{ 2, 16 },{ 45, 16 },{ 76, 66 },{ 27, 51 },{ 36, 75 },{ 5, 47 },
+ { 11, 22 },{ 57, 24 },{ 64, 56 },{ 39, 39 },{ 15, 78 },{ 54, 1 },{ 77, 2 },{ 26, 18 },
+ { 72, 27 },{ 41, 49 },{ 71, 53 },{ 21, 30 },{ 5, 71 },{ 44, 65 },{ 57, 36 },{ 61, 78 },
+ { 25, 43 },{ 40, 18 },{ 21, 73 },{ 4, 29 },{ 75, 41 },{ 35, 61 },{ 48, 4 },{ 10, 51 },
+ { 58, 14 },{ 55, 61 },{ 12, 13 },{ 30, 35 },{ 70, 18 },{ 21, 64 },{ 51, 30 },{ 30, 0 },
+ { 68, 65 },{ 15, 37 },{ 58, 42 },{ 71, 5 },{ 38, 25 },{ 7, 61 },{ 31, 54 },{ 54, 71 },
+ { 22, 16 },{ 70, 35 },{ 40, 72 },{ 9, 6 },{ 75, 51 },{ 36, 12 },{ 53, 50 },{ 4, 20 },
+ { 13, 47 },{ 52, 14 },{ 0, 76 },{ 33, 42 },{ 65, 25 },{ 22, 55 },{ 10, 29 },{ 61, 63 },
+ { 17, 7 },{ 43, 32 },{ 12, 70 },{ 38, 4 },{ 66, 1 },{ 0, 44 },{ 40, 54 },{ 30, 23 },
+ { 49, 77 },{ 76, 12 },{ 74, 69 },{ 48, 37 },{ 26, 78 },{ 65, 47 },{ 17, 20 },{ 47, 11 },
+ { 28, 45 },{ 0, 56 },{ 77, 21 },{ 51, 62 },{ 63, 33 },{ 9, 75 },{ 25, 29 },{ 62, 7 },
+ { 47, 47 },{ 18, 65 },{ 9, 42 },{ 42, 22 },{ 40, 62 },{ 66, 70 },{ 78, 31 },{ 24, 5 },
+ { 54, 24 },{ 18, 51 },{ 59, 57 },{ 7, 11 },{ 33, 67 },{ 55, 6 },{ 16, 32 },{ 64, 41 },
+ { 32, 9 },{ 10, 66 },{ 65, 18 },{ 40, 35 },{ 45, 70 },{ 78, 61 },{ 33, 52 },{ 68, 10 },
+ { 10, 17 },{ 57, 52 },{ 28, 73 },{ 18, 40 },{ 55, 32 },{ 3, 52 },{ 33, 17 },{ 75, 75 },
+ { 56, 68 },{ 74, 38 },{ 17, 73 },{ 42, 78 },{ 29, 28 },{ 52, 41 },{ 17, 59 },{ 71, 23 },
+ { 17, 25 },{ 69, 54 },{ 53, 16 },{ 37, 41 },{ 5, 4 },{ 30, 62 },{ 10, 36 },{ 39, 11 },
+ { 65, 76 },{ 45, 51 },{ 22, 13 },{ 61, 27 },{ 24, 47 },{ 0, 71 },{ 1, 26 },{ 49, 58 },
+ { 13, 3 },{ 47, 29 },{ 59, 73 },{ 71, 45 },{ 34, 77 },{ 12, 56 },{ 74, 9 },{ 34, 33 },
+ { 67, 59 },{ 47, 19 },{ 24, 69 },{ 3, 35 },{ 27, 21 },{ 37, 57 },{ 0, 18 },{ 58, 10 },
+ { 26, 39 },{ 9, 47 },{ 49, 74 },{ 60, 45 },{ 5, 64 },{ 15, 12 },{ 42, 8 },{ 62, 22 },
+ { 24, 53 },{ 74, 56 },{ 73, 32 },{ 41, 68 },{ 45, 37 },{ 74, 2 },{ 10, 25 },{ 22, 76 },
+ { 39, 48 },{ 70, 68 },{ 30, 12 },{ 64, 51 },{ 21, 36 },{ 55, 77 },{ 68, 14 },{ 10, 1 },
+ { 35, 21 },{ 61, 37 },{ 26, 64 },{ 52, 66 },{ 51, 26 },{ 5, 57 },{ 7, 31 },{ 38, 1 },
+ { 76, 48 },{ 1, 7 },{ 32, 47 },{ 51, 48 },{ 26, 5 },{ 49, 10 },{ 18, 46 },{ 66, 4 },
+ { 38, 27 },{ 7, 73 },{ 7, 16 },{ 62, 65 },{ 1, 39 },{ 34, 59 },{ 20, 19 },{ 56, 40 },
+ { 69, 31 },{ 13, 66 },{ 46, 62 },{ 43, 20 },{ 19, 30 },{ 74, 63 },{ 73, 20 },{ 37, 72 },
+ { 44, 44 },{ 13, 50 },{ 58, 2 },{ 20, 9 },{ 53, 57 },{ 31, 39 },{ 60, 19 },{ 3, 76 },
+ { 24, 59 },{ 46, 4 },{ 5, 42 },{ 32, 26 },{ 69, 73 },{ 69, 48 },{ 14, 17 },{ 53, 29 },
+ { 32, 4 },{ 43, 54 },{ 76, 29 },{ 78, 68 },{ 15, 75 },{ 13, 33 },{ 61, 59 },{ 63, 13 },
+ { 8, 54 },{ 42, 15 },{ 28, 70 },{ 1, 13 },{ 48, 41 },{ 24, 27 },{ 59, 32 },{ 44, 73 },
+ { 19, 55 },{ 12, 8 },{ 72, 43 },{ 35, 51 },{ 54, 10 },{ 58, 49 },{ 6, 23 },{ 38, 32 },
+ { 23, 1 },{ 57, 64 },{ 13, 41 },{ 77, 5 },{ 2, 61 },{ 53, 20 },{ 30, 15 },{ 61, 76 },
+ { 29, 43 },{ 22, 66 },{ 67, 35 },{ 50, 1 },{ 71, 12 },{ 5, 49 },{ 37, 66 },{ 28, 33 },
+ { 66, 61 },{ 45, 25 },{ 48, 53 },{ 13, 60 },{ 36, 7 },{ 68, 24 },{ 18, 23 },{ 28, 57 },
+ { 76, 78 },{ 53, 44 },{ 18, 5 },{ 77, 37 },{ 53, 70 },{ 7, 68 },{ 20, 43 },{ 31, 75 },
+ { 66, 7 },{ 49, 34 },{ 12, 28 },{ 37, 17 },{ 75, 59 },{ 41, 59 },{ 64, 54 },{ 4, 9 },
+ { 59, 25 },{ 39, 45 },{ 24, 18 },{ 1, 45 },{ 47, 14 },{ 12, 77 },{ 76, 23 },{ 64, 73 },
+ { 22, 50 },{ 65, 40 },{ 44, 1 },{ 18, 68 },{ 9, 21 },{ 39, 37 },{ 49, 65 },{ 9, 38 },
+ { 26, 10 },{ 72, 73 },{ 65, 28 },{ 57, 15 },{ 27, 37 },{ 72, 52 },{ 32, 63 },{ 3, 1 },
+ { 55, 4 },{ 40, 24 },{ 15, 53 },{ 73, 16 },{ 55, 55 },{ 20, 75 },{ 55, 36 },{ 18, 14 },
+ { 40, 76 },{ 10, 62 },{ 5, 28 },{ 33, 31 },{ 65, 66 },{ 30, 52 },{ 68, 3 },{ 1, 54 },
+ { 29, 2 },{ 72, 35 },{ 43, 41 },{ 17, 36 },{ 55, 73 },{ 3, 71 },{ 50, 22 },{ 62, 48 },
+ { 24, 23 },{ 36, 69 },{ 6, 12 },{ 47, 58 },{ 61, 10 },{ 10, 44 },{ 41, 12 },{ 18, 62 },
+ { 70, 28 },{ 39, 51 },{ 70, 62 },{ 15, 8 },{ 44, 31 },{ 23, 31 },{ 66, 43 },{ 23, 72 },
+ { 77, 17 },{ 51, 8 },{ 27, 48 },{ 55, 47 },{ 34, 10 },{ 60, 69 },{ 78, 41 },{ 64, 22 },
+ { 1, 66 },{ 43, 62 },{ 33, 21 },{ 9, 2 },{ 47, 76 },{ 3, 33 },{ 34, 44 },{ 71, 7 },
+ { 15, 27 },{ 6, 59 },{ 51, 36 },{ 36, 1 },{ 32, 56 },{ 77, 49 },{ 19, 1 },{ 55, 22 },
+ { 15, 46 },{ 63, 78 },{ 51, 51 },{ 3, 21 },{ 12, 72 },{ 72, 67 },{ 27, 16 },{ 23, 40 },
+ { 45, 7 },{ 59, 34 },{ 58, 59 },{ 24, 63 },{ 78, 9 },{ 36, 29 },{ 40, 66 },{ 63, 17 },
+ { 14, 19 },{ 71, 56 },{ 44, 47 },{ 28, 77 },{ 50, 18 },{ 8, 50 },{ 50, 70 },{ 76, 26 },
+ { 34, 37 },{ 72, 76 },{ 10, 11 },{ 61, 43 },{ 20, 26 },{ 31, 69 },{ 5, 38 },{ 21, 58 },
+ { 60, 1 },{ 43, 27 },{ 28, 8 },{ 68, 37 },{ 6, 76 },{ 54, 63 },{ 69, 19 },{ 24, 44 },
+ { 59, 54 },{ 39, 6 },{ 11, 58 },{ 29, 24 },{ 74, 46 },{ 0, 2 },{ 43, 37 },{ 56, 7 },
+ { 10, 31 },{ 17, 71 },{ 64, 30 },{ 42, 72 },{ 21, 12 },{ 66, 56 },{ 27, 54 },{ 44, 17 },
+ { 75, 70 },{ 50, 42 },{ 16, 39 },{ 3, 15 },{ 45, 56 },{ 65, 10 },{ 55, 27 },{ 34, 74 },
+ { 7, 66 },{ 30, 31 },{ 77, 33 },{ 53, 78 },{ 1, 51 },{ 36, 14 },{ 36, 49 },{ 15, 5 },
+ { 67, 74 },{ 12, 23 },{ 34, 62 },{ 68, 46 },{ 49, 13 },{ 19, 53 },{ 74, 12 },{ 63, 63 },
+ { 49, 28 },{ 22, 35 },{ 23, 8 },{ 7, 44 },{ 58, 40 },{ 0, 73 },{ 45, 67 },{ 2, 25 },
+ { 26, 66 },{ 38, 23 },{ 77, 62 },{ 60, 15 },{ 38, 40 },{ 51, 55 },{ 14, 65 },{ 43, 4 },
+ { 9, 8 },{ 72, 25 },{ 58, 72 },{ 28, 41 },{ 24, 77 },{ 70, 40 },{ 39, 58 },{ 14, 34 },
+ { 73, 3 },{ 30, 19 },{ 56, 33 },{ 4, 56 },{ 6, 18 },{ 51, 4 },{ 48, 46 },{ 15, 49 },
+ { 16, 16 },{ 65, 50 },{ 46, 22 },{ 30, 59 },{ 63, 6 },{ 13, 0 },{ 55, 66 },{ 31, 1 },
+ { 6, 34 },{ 76, 53 },{ 59, 21 },{ 27, 28 },{ 10, 71 },{ 67, 69 },{ 41, 34 },{ 67, 15 },
+ { 22, 47 },{ 63, 37 },{ 47, 72 },{ 23, 15 },{ 43, 51 },{ 2, 4 },{ 76, 42 },{ 21, 61 },
+ { 35, 5 },{ 70, 60 },{ 56, 45 },{ 1, 29 },{ 53, 13 },{ 30, 49 },{ 18, 29 },{ 68, 78 },
+ { 21, 69 },{ 39, 19 },{ 49, 60 },{ 11, 52 },{ 75, 19 },{ 62, 28 },{ 32, 38 },{ 37, 76 },
+ { 3, 67 },{ 46, 34 },{ 28, 12 },{ 3, 46 },{ 58, 77 },{ 11, 14 },{ 37, 63 },{ 12, 39 },
+ { 62, 53 },{ 17, 78 },{ 44, 11 },{ 41, 45 },{ 6, 3 },{ 70, 33 },{ 22, 24 },{ 0, 58 },
+ { 59, 65 },{ 27, 72 },{ 69, 9 },{ 35, 26 },{ 16, 58 },{ 53, 31 },{ 46, 78 },{ 7, 26 },
+ { 34, 54 },{ 56, 51 },{ 18, 43 },{ 78, 77 },{ 55, 18 },{ 25, 4 },{ 73, 64 },{ 67, 21 },
+ { 50, 39 },{ 2, 37 },{ 51, 68 },{ 78, 11 },{ 29, 36 },{ 40, 2 },{ 72, 49 },{ 18, 11 },
+ { 12, 68 },{ 26, 59 },{ 60, 7 },{ 34, 15 },{ 53, 60 },{ 73, 30 },{ 14, 22 },{ 36, 46 },
+ { 8, 60 },{ 50, 25 },{ 39, 69 },{ 63, 71 },{ 21, 32 },{ 5, 73 },{ 36, 33 },{ 71, 15 },
+ { 61, 39 },{ 13, 45 },{ 29, 66 },{ 48, 5 },{ 68, 53 },{ 26, 22 },{ 0, 20 },{ 47, 49 },
+ { 10, 5 },{ 25, 50 },{ 58, 12 },{ 63, 59 },{ 6, 52 },{ 31, 7 },{ 70, 0 },{ 73, 39 },
+ { 46, 30 },{ 52, 75 },{ 20, 2 },{ 43, 57 },{ 8, 30 },{ 60, 30 },{ 75, 67 },{ 33, 72 },
+ { 31, 43 },{ 41, 20 },{ 17, 63 },{ 76, 6 },{ 55, 42 },{ 19, 18 },{ 8, 40 },{ 41, 9 },
+ { 9, 77 },{ 47, 64 },{ 67, 27 },{ 20, 40 },{ 9, 18 },{ 2, 63 },{ 60, 3 },{ 64, 44 },
+ { 45, 42 },{ 14, 56 },{ 31, 27 },{ 47, 16 },{ 24, 74 },{ 68, 64 },{ 38, 54 },{ 76, 35 },
+ { 3, 12 },{ 42, 75 },{ 58, 22 },{ 71, 72 },{ 56, 57 },{ 25, 31 },{ 3, 42 },{ 25, 55 },
+ { 33, 11 },{ 73, 55 },{ 40, 30 },{ 14, 74 },{ 53, 2 },{ 71, 21 },{ 39, 61 },{ 12, 25 },
+ { 53, 37 },{ 70, 4 },{ 19, 6 },{ 19, 49 },{ 56, 70 },{ 65, 33 },{ 31, 17 },{ 52, 52 },
+ { 9, 65 },{ 34, 66 },{ 11, 35 },{ 51, 20 },{ 0, 47 },{ 76, 74 },{ 36, 42 },{ 5, 8 },
+ { 27, 0 },{ 64, 19 },{ 60, 49 },{ 78, 26 },{ 50, 9 },{ 19, 67 },{ 25, 38 },{ 24, 21 },
+ { 62, 69 },{ 42, 25 },{ 70, 43 },{ 33, 78 },{ 10, 48 },{ 77, 15 },{ 42, 48 },{ 15, 10 },
+ { 44, 69 },{ 76, 57 },{ 65, 3 },{ 38, 12 },{ 29, 61 },{ 19, 34 },{ 57, 28 },{ 58, 61 },
+ { 4, 0 },{ 6, 21 },{ 47, 38 },{ 3, 60 },{ 29, 46 },{ 49, 0 },{ 34, 23 },{ 20, 72 },
+ { 68, 49 },{ 64, 14 },{ 34, 57 },{ 1, 31 },{ 24, 10 },{ 2, 70 },{ 47, 54 },{ 17, 22 },
+ { 55, 12 },{ 17, 52 },{ 63, 35 },{ 61, 74 },{ 31, 34 },{ 39, 73 },{ 75, 10 },{ 67, 57 },
+ { 50, 31 },{ 13, 63 },{ 77, 44 },{ 29, 5 },{ 54, 48 },{ 13, 30 },{ 7, 14 },{ 40, 15 },
+ { 43, 64 },{ 75, 0 },{ 41, 40 },{ 8, 56 },{ 63, 24 },{ 14, 2 },{ 15, 43 },{ 51, 72 },
+ { 70, 66 },{ 27, 69 },{ 46, 8 },{ 73, 36 },{ 37, 34 },{ 33, 50 },{ 1, 22 },{ 48, 24 },
+ { 3, 50 },{ 61, 56 },{ 13, 16 },{ 23, 56 },{ 65, 78 },{ 35, 2 },{ 22, 42 },{ 57, 43 },
+ { 10, 74 },{ 67, 11 },{ 25, 17 },{ 50, 63 },{ 7, 36 },{ 52, 16 },{ 71, 29 },{ 23, 64 },
+ { 20, 28 },{ 56, 78 },{ 77, 65 },{ 41, 52 },{ 37, 20 },{ 19, 76 },{ 74, 50 },{ 58, 37 },
+ { 73, 7 },{ 30, 73 },{ 35, 39 },{ 37, 9 },{ 65, 62 },{ 73, 24 },{ 50, 47 },{ 6, 46 },
+ { 6, 6 },{ 57, 8 },{ 26, 27 },{ 28, 52 },{ 6, 69 },{ 55, 25 },{ 43, 78 },{ 14, 37 },
+ { 20, 14 },{ 66, 39 },{ 58, 68 },{ 45, 60 },{ 5, 30 },{ 44, 33 },{ 14, 54 },{ 61, 17 },
+ { 2, 77 },{ 34, 69 },{ 67, 72 },{ 22, 5 },{ 44, 22 },{ 74, 60 },{ 10, 20 },{ 63, 47 },
+ { 26, 47 },{ 31, 21 },{ 36, 60 },{ 73, 18 },{ 16, 67 },{ 47, 2 },{ 67, 31 },{ 4, 40 },
+ { 39, 28 },{ 52, 58 },{ 13, 9 },{ 6, 62 },{ 24, 35 },{ 63, 9 },{ 45, 45 },{ 46, 12 },
+ { 73, 44 },{ 26, 62 },{ 3, 18 },{ 58, 53 },{ 29, 14 },{ 73, 72 },{ 21, 51 },{ 54, 33 },
+ { 39, 3 },{ 16, 26 },{ 0, 4 },{ 54, 74 },{ 5, 54 },{ 42, 67 },{ 32, 41 },{ 75, 33 },
+ { 16, 2 },{ 56, 16 },{ 27, 76 },{ 11, 43 },{ 51, 43 },{ 65, 68 },{ 34, 30 },{ 18, 60 },
+ { 67, 23 },{ 57, 3 },{ 4, 25 },{ 37, 51 },{ 69, 52 },{ 8, 78 },{ 26, 7 },{ 46, 26 },
+ { 56, 62 },{ 70, 13 },{ 17, 38 },{ 0, 69 },{ 31, 65 },{ 22, 19 },{ 61, 31 },{ 48, 71 },
+ { 78, 36 },{ 42, 38 },{ 12, 59 },{ 67, 2 },{ 43, 13 },{ 8, 10 },{ 62, 41 },{ 49, 55 },
+ { 16, 72 },{ 28, 29 },{ 0, 52 },{ 52, 7 },{ 30, 55 },{ 9, 28 },{ 38, 78 },{ 71, 59 },
+ { 34, 18 },{ 0, 14 },{ 20, 46 },{ 52, 28 },{ 72, 0 },{ 34, 47 },{ 61, 51 },{ 24, 71 },
+ { 17, 31 },{ 33, 8 },{ 69, 42 },{ 51, 65 },{ 61, 20 },{ 9, 70 },{ 17, 13 },{ 40, 57 },
+ { 48, 35 },{ 12, 49 },{ 63, 76 },{ 77, 28 },{ 48, 18 },{ 1, 57 },{ 27, 40 },{ 22, 1 },
+ { 62, 60 },{ 38, 71 },{ 3, 7 },{ 54, 40 },{ 68, 17 },{ 31, 24 },{ 48, 75 },{ 1, 41 },
+ { 1, 74 },{ 40, 44 },{ 16, 19 },{ 41, 6 },{ 17, 56 },{ 60, 11 },{ 10, 33 },{ 73, 68 },
+ { 54, 53 },{ 23, 67 },{ 62, 26 },{ 12, 5 },{ 38, 36 },{ 67, 47 },{ 39, 64 },{ 25, 12 },
+ { 74, 5 },{ 10, 54 },{ 53, 23 },{ 23, 25 },{ 61, 66 },{ 68, 34 },{ 31, 78 },{ 46, 50 },
+ { 21, 38 },{ 75, 22 },{ 57, 76 },{ 41, 17 },{ 23, 60 },{ 4, 66 },{ 8, 24 },{ 58, 45 },
+ { 61, 5 },{ 76, 39 },{ 12, 75 },{ 32, 59 },{ 43, 29 },{ 9, 15 },{ 8, 45 },{ 53, 11 },
+ { 47, 68 },{ 29, 34 },{ 69, 76 },{ 74, 52 },{ 30, 9 },{ 24, 51 },{ 69, 26 },{ 65, 58 },
+ { 20, 78 },{ 37, 24 },{ 72, 10 },{ 45, 39 },{ 44, 76 },{ 10, 64 },{ 4, 32 },{ 42, 53 },
+ { 18, 8 },{ 57, 32 },{ 17, 45 },{ 75, 62 },{ 50, 5 },{ 35, 73 },{ 27, 19 },{ 54, 67 },
+ { 30, 45 },{ 1, 1 },{ 78, 19 },{ 4, 48 },{ 57, 18 },{ 52, 45 },{ 20, 63 },{ 19, 24 },
+ { 65, 53 },{ 67, 6 },{ 37, 13 },{ 16, 34 },{ 44, 59 },{ 65, 37 },{ 26, 2 },{ 69, 67 },
+ { 48, 21 },{ 5, 75 },{ 35, 53 },{ 75, 45 },{ 5, 13 },{ 32, 68 },{ 35, 32 },{ 10, 41 },
+ { 44, 5 },{ 50, 33 },{ 15, 70 },{ 74, 27 },{ 60, 72 },{ 24, 42 },{ 13, 12 },{ 1, 60 },
+ { 57, 58 },{ 59, 26 },{ 34, 4 },{ 38, 43 },{ 74, 15 },{ 26, 57 },{ 51, 77 },{ 14, 28 },
+ { 50, 14 },{ 50, 50 },{ 76, 76 },{ 9, 57 },{ 26, 33 },{ 70, 38 },{ 11, 3 },{ 40, 22 },
+ { 62, 2 },{ 36, 65 },{ 4, 37 },{ 70, 55 },{ 20, 17 },{ 65, 15 },{ 52, 38 },{ 43, 71 },
+ { 14, 61 },{ 4, 22 },{ 27, 74 },{ 62, 44 },{ 32, 16 },{ 64, 64 },{ 18, 48 },{ 0, 8 },
+ { 47, 61 },{ 33, 27 },{ 77, 69 },{ 37, 47 },{ 22, 9 },{ 66, 29 },{ 56, 5 },{ 17, 75 },
+ { 1, 49 },{ 2, 28 },{ 44, 36 },{ 40, 8 },{ 21, 55 },{ 57, 50 },{ 12, 21 },{ 44, 19 },
+ { 66, 73 },{ 28, 63 },{ 16, 41 },{ 65, 20 },{ 77, 56 },{ 30, 37 },{ 35, 76 },{ 7, 4 },
+ { 59, 36 },{ 59, 13 },{ 11, 67 },{ 53, 62 },{ 28, 22 },{ 70, 47 },{ 38, 56 },{ 68, 8 },
+ { 8, 37 },{ 22, 29 },{ 41, 1 },{ 72, 63 },{ 48, 30 },{ 46, 43 },{ 75, 30 },{ 22, 71 },
+ { 31, 50 },{ 48, 9 },{ 76, 1 },{ 7, 53 },{ 4, 16 },{ 55, 69 },{ 56, 23 },{ 27, 13 },
+ { 41, 63 },{ 73, 42 },{ 16, 6 },{ 60, 55 },{ 6, 72 },{ 40, 32 },{ 23, 46 },{ 59, 0 },
+ { 70, 20 },{ 30, 3 },{ 11, 27 },{ 5, 61 },{ 46, 53 },{ 70, 71 },{ 34, 41 },{ 78, 34 },
+ { 36, 16 },{ 28, 67 },{ 15, 15 },{ 15, 51 },{ 62, 32 },{ 50, 73 },{ 77, 13 },{ 68, 60 },
+ { 20, 35 },{ 52, 25 },{ 14, 77 },{ 55, 49 },{ 4, 43 },{ 46, 15 },{ 31, 57 },{ 20, 22 },
+ { 51, 2 },{ 0, 64 },{ 65, 42 },{ 71, 3 },{ 32, 74 },{ 40, 26 },{ 60, 64 },{ 17, 66 },
+ { 77, 24 },{ 43, 49 },{ 10, 9 },{ 12, 46 },{ 46, 65 },{ 32, 30 },{ 63, 11 },{ 55, 39 },
+ { 24, 3 },{ 12, 32 },{ 71, 51 },{ 36, 10 },{ 6, 0 },{ 27, 44 },{ 54, 14 },{ 71, 34 },
+ { 51, 57 },{ 41, 73 },{ 20, 57 },{ 73, 75 },{ 56, 30 },{ 7, 20 },{ 36, 37 },{ 2, 53 },
+ { 24, 14 },{ 57, 74 },{ 33, 64 },{ 65, 23 },{ 49, 43 },{ 1, 11 },{ 28, 25 },{ 8, 63 },
+ { 37, 5 },{ 13, 38 },{ 66, 49 },{ 65, 5 },{ 23, 78 },{ 26, 52 },{ 78, 72 },{ 44, 26 },
+ { 0, 38 },{ 45, 3 },{ 64, 69 },{ 40, 47 },{ 14, 24 },{ 52, 19 },{ 13, 71 },{ 59, 44 },
+ { 71, 17 },{ 37, 59 },{ 24, 32 },{ 9, 49 },{ 50, 67 },{ 19, 4 },{ 72, 57 },{ 34, 20 },
+ { 55, 9 },{ 6, 27 },{ 25, 68 },{ 77, 47 },{ 75, 8 },{ 52, 35 },{ 60, 61 },{ 31, 10 },
+ { 15, 59 },{ 29, 40 },{ 70, 24 },{ 66, 77 },{ 37, 68 },{ 10, 13 },{ 48, 56 },{ 41, 36 },
+ { 44, 9 },{ 5, 68 },{ 68, 39 },{ 19, 39 },{ 60, 22 },{ 63, 55 },{ 17, 18 },{ 3, 3 },
+ { 29, 54 },{ 55, 0 },{ 6, 32 },{ 19, 74 },{ 38, 29 },{ 13, 53 },{ 61, 35 },{ 45, 77 },
+ { 28, 6 },{ 49, 48 },{ 1, 17 },{ 69, 63 },{ 43, 16 },{ 2, 44 },{ 67, 13 },{ 33, 46 },
+ { 19, 64 },{ 25, 26 },{ 10, 78 },{ 54, 59 },{ 72, 32 },{ 29, 71 },{ 47, 27 },{ 3, 57 },
+ { 59, 9 },{ 41, 42 },{ 17, 28 },{ 42, 69 },{ 76, 71 },{ 23, 49 },{ 21, 10 },{ 67, 44 },
+ { 56, 20 },{ 57, 66 },{ 34, 1 },{ 7, 39 },{ 77, 3 },{ 28, 18 },{ 41, 55 },{ 63, 29 },
+ { 27, 60 },{ 76, 60 },{ 2, 23 },{ 62, 0 },{ 25, 36 },{ 48, 39 },{ 11, 7 },{ 59, 48 },
+ { 39, 17 },{ 10, 59 },{ 53, 73 },{ 14, 44 },{ 70, 11 },{ 33, 34 },{ 74, 40 },{ 39, 75 },
+ { 11, 19 },{ 3, 74 },{ 49, 7 },{ 33, 61 },{ 75, 49 },{ 68, 70 },{ 54, 30 },{ 15, 0 },
+ { 36, 22 },{ 52, 54 },{ 2, 34 },{ 18, 54 },{ 62, 18 },{ 25, 76 },{ 21, 20 },{ 45, 63 },
+ { 46, 32 },{ 4, 11 },{ 63, 52 },{ 6, 50 },{ 51, 12 },{ 22, 44 },{ 36, 52 },{ 73, 22 },
+ { 31, 13 },{ 71, 77 },{ 12, 65 },{ 59, 39 },{ 18, 33 },{ 66, 65 },{ 53, 5 },{ 20, 70 },
+ { 68, 28 },{ 16, 11 },{ 46, 70 },{ 28, 31 },{ 2, 65 },{ 46, 46 },{ 45, 21 },{ 9, 35 },
+ { 33, 6 },{ 69, 5 },{ 78, 54 },{ 58, 70 },{ 31, 48 },{ 9, 73 },{ 78, 29 },{ 30, 77 },
+ { 53, 42 },{ 75, 13 },{ 40, 60 },{ 22, 62 },{ 58, 24 },{ 42, 11 },{ 68, 56 },{ 8, 22 },
+ { 39, 41 },{ 48, 78 },{ 66, 36 },{ 21, 15 },{ 14, 48 },{ 74, 66 },{ 34, 25 },{ 8, 7 },
+ { 56, 54 },{ 61, 13 },{ 22, 53 },{ 33, 70 },{ 72, 46 },{ 64, 75 },{ 16, 30 },{ 49, 20 },
+ { 25, 8 },{ 33, 39 },{ 1, 78 },{ 52, 64 },{ 8, 43 },{ 76, 20 },{ 42, 31 },{ 39, 0 },
+ { 33, 55 },{ 75, 37 },{ 59, 4 },{ 14, 68 },{ 23, 22 },{ 57, 34 },{ 7, 58 },{ 17, 3 },
+ { 44, 52 },{ 60, 58 },{ 24, 39 },{ 8, 17 },{ 66, 17 },{ 39, 67 },{ 64, 48 },{ 77, 7 },
+ { 40, 13 },{ 24, 65 },{ 50, 29 },{ 0, 42 },{ 73, 70 },{ 17, 42 },{ 43, 2 },{ 53, 46 },
+ { 3, 27 },{ 30, 29 },{ 59, 75 },{ 64, 26 },{ 4, 63 },{ 48, 59 },{ 28, 1 },{ 8, 1 },
+ { 54, 17 },{ 38, 49 },{ 75, 55 },{ 15, 21 },{ 64, 7 },{ 16, 62 },{ 33, 14 },{ 63, 40 },
+ { 12, 36 },{ 41, 23 },{ 28, 47 },{ 73, 1 },{ 30, 64 },{ 70, 30 },{ 47, 74 },{ 65, 60 },
+ { 44, 40 },{ 22, 74 },{ 9, 52 },{ 2, 9 },{ 19, 27 },{ 38, 7 },{ 4, 70 },{ 35, 35 },
+ { 61, 70 },{ 72, 14 },{ 50, 37 },{ 19, 12 },{ 0, 32 },{ 27, 56 },{ 54, 3 },{ 70, 50 },
+ { 29, 21 },{ 43, 61 },{ 49, 15 },{ 9, 26 },{ 54, 51 },{ 11, 76 },{ 17, 50 },{ 60, 28 },
+ { 37, 74 },{ 5, 45 },{ 58, 63 },{ 23, 6 },{ 68, 75 },{ 26, 42 },{ 2, 19 },{ 51, 23 },
+ { 76, 64 },{ 57, 41 },{ 35, 58 },{ 14, 7 },{ 72, 37 },{ 22, 33 },{ 52, 71 },{ 59, 16 },
+ { 18, 58 },{ 37, 26 },{ 26, 70 },{ 78, 50 },{ 11, 16 },{ 46, 10 },{ 35, 43 },{ 8, 67 },
+ { 70, 8 },{ 75, 25 },{ 48, 51 },{ 26, 15 },{ 72, 61 },{ 14, 40 },{ 48, 66 },{ 43, 34 },
+ { 78, 75 },{ 32, 2 },{ 64, 34 },{ 11, 55 },{ 58, 6 },{ 61, 46 },{ 18, 0 },{ 11, 30 },
+ { 35, 67 },{ 36, 18 },{ 4, 6 },{ 69, 22 },{ 42, 46 },{ 64, 1 },{ 3, 39 },{ 53, 27 },
+ { 63, 66 },{ 27, 35 },{ 23, 58 },{ 49, 3 },{ 17, 69 },{ 69, 45 },{ 21, 25 },{ 58, 56 },
+ { 78, 16 },{ 29, 11 },{ 78, 59 },{ 43, 74 },{ 29, 51 },{ 54, 35 },{ 43, 24 },{ 4, 77 },
+ { 44, 55 },{ 8, 12 },{ 19, 44 },{ 65, 12 },{ 29, 75 },{ 75, 43 },{ 37, 31 },{ 54, 76 },
+ { 4, 51 },{ 43, 7 },{ 66, 54 },{ 7, 29 },{ 12, 62 },{ 38, 62 },{ 25, 20 },{ 68, 32 },
+ { 75, 4 },{ 47, 41 },{ 56, 14 },{ 67, 67 },{ 14, 14 },{ 32, 44 },{ 21, 3 },{ 15, 35 },
+ { 51, 60 },{ 46, 18 },{ 1, 68 },{ 63, 21 },{ 36, 78 },{ 10, 46 },{ 20, 66 },{ 73, 28 },
+ { 30, 26 },{ 57, 47 },{ 67, 0 },{ 31, 61 },{ 13, 73 },{ 40, 38 },{ 5, 35 },{ 55, 64 },
+ { 39, 10 },{ 5, 19 },{ 20, 52 },{ 72, 54 },{ 56, 26 },{ 39, 53 },{ 9, 4 },{ 52, 10 },
+ { 16, 24 },{ 71, 69 },{ 67, 41 },{ 31, 72 },{ 22, 37 },{ 48, 33 },{ 72, 19 },{ 44, 66 },
+ { 6, 55 },{ 27, 4 },{ 62, 73 },{ 32, 23 },{ 73, 11 },{ 52, 49 },{ 8, 71 },{ 26, 49 },
+ { 52, 0 },{ 78, 45 },{ 18, 16 },{ 0, 25 },{ 32, 36 },{ 35, 8 },{ 60, 33 },{ 67, 62 },
+ { 25, 61 },{ 74, 77 },{ 47, 23 },{ 40, 70 },{ 10, 39 },{ 62, 50 },{ 61, 8 },{ 17, 9 },
+ { 4, 59 },{ 26, 30 },{ 49, 45 },{ 21, 77 },{ 66, 25 },{ 49, 69 },{ 74, 34 },{ 34, 49 },
+ { 1, 5 },{ 38, 15 },{ 13, 57 },{ 46, 1 },{ 10, 23 },{ 46, 57 },{ 58, 19 },{ 41, 28 },
+ { 74, 58 },{ 21, 41 },{ 60, 42 },{ 12, 1 },{ 27, 65 },{ 2, 14 },{ 56, 60 },{ 23, 17 },
+ { 75, 73 },{ 16, 47 },{ 48, 12 },{ 1, 36 },{ 37, 39 },{ 60, 77 },{ 18, 72 },{ 37, 3 },
+ { 69, 15 },{ 56, 37 },{ 36, 56 },{ 2, 47 },{ 32, 19 },{ 6, 65 },{ 14, 32 },{ 63, 57 },
+ { 69, 2 },{ 27, 9 },{ 45, 48 },{ 49, 26 },{ 71, 41 },{ 53, 68 },{ 6, 9 },{ 24, 54 },
+ { 36, 71 },{ 23, 28 },{ 57, 11 },{ 3, 30 },{ 77, 67 },{ 46, 36 },{ 25, 73 },{ 30, 42 },
+ { 67, 51 },{ 65, 31 },{ 7, 75 },{ 41, 77 },{ 42, 19 },{ 13, 18 },{ 16, 55 },{ 66, 9 },
+ { 54, 56 },{ 7, 48 },{ 78, 22 },{ 56, 72 },{ 35, 28 },{ 20, 7 },{ 15, 64 },{ 61, 24 },
+ { 40, 50 },{ 76, 52 },{ 47, 6 },{ 35, 63 },{ 18, 37 },{ 78, 0 },{ 52, 32 },{ 65, 71 },
+ { 29, 16 },{ 69, 36 },{ 25, 45 },{ 75, 17 },{ 62, 62 },{ 31, 5 },{ 55, 44 },{ 6, 41 },
+ { 14, 4 },{ 57, 1 },{ 29, 58 },{ 13, 26 },{ 54, 21 },{ 9, 61 },{ 41, 65 },{ 31, 32 },
+ { 72, 6 },{ 43, 43 },{ 0, 62 },{ 22, 68 },{ 44, 14 },{ 6, 15 },{ 65, 45 },{ 76, 31 },
+ { 45, 72 },{ 18, 21 },{ 62, 15 },{ 71, 65 },{ 50, 53 },{ 25, 0 },{ 12, 51 },{ 45, 29 },
+ { 2, 72 },{ 28, 38 },{ 54, 7 },{ 73, 48 },{ 33, 76 },{ 71, 26 },{ 8, 33 },{ 42, 58 },
+ { 34, 12 },{ 12, 11 },{ 37, 45 },{ 62, 38 },{ 11, 69 },{ 63, 4 },{ 21, 48 },{ 26, 24 },
+ { 69, 58 },{ 50, 76 },{ 5, 2 },{ 58, 29 },{ 38, 21 },{ 59, 67 },{ 20, 60 },{ 77, 40 },
+ { 77, 10 },{ 20, 31 },{ 51, 40 },{ 32, 53 },{ 16, 76 },{ 41, 4 },{ 67, 19 },{ 49, 62 },
+ { 2, 55 },{ 23, 12 },{ 12, 42 },{ 39, 34 },{ 70, 74 },{ 51, 17 },{ 59, 52 },{ 30, 68 },
+ { 5, 24 }
+};
+
+static ccoord *screens0[1] = {
+ screen0_0
+};
+
+#define NO_SCREENS 1
+static thscdef screens[NO_SCREENS] = {
+ {
+ 79, /* Size */
+ 79, /* Width */
+ 79, /* Height */
+ 1.000000, /* Aspect Ratio */
+ 1, /* Joint screens */
+ screens0 /* list of pointers to screen threshold arrays */
+ }
+};
+
diff --git a/render/thscreen.c b/render/thscreen.c
new file mode 100644
index 0000000..c0a5548
--- /dev/null
+++ b/render/thscreen.c
@@ -0,0 +1,474 @@
+
+/*
+ * render2d
+ *
+ * Threshold screen pixel processing object.
+ * (Simplified from DPS code)
+ *
+ * Author: Graeme W. Gill
+ * Date: 8/9/2005
+ * Version: 1.00
+ *
+ * Copyright 2005, 2012 Graeme W. Gill
+ * All rights reserved.
+ * This material is licenced under the GNU AFFERO GENERAL PUBLIC LICENSE Version 3 :-
+ * see the License.txt file for licencing details.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <fcntl.h>
+#include <string.h>
+#include <math.h>
+#include "aconfig.h"
+#include "numlib.h"
+//#include "icc.h"
+#include "sort.h"
+//#include "xcolorants.h"
+#include "thscreen.h"
+
+/* Configuration: */
+#undef DEBUG
+
+/* ----------------------------------------------------------- */
+
+#ifdef DEBUG
+# define DBG(text) printf text ; fflush(stdout);
+#else
+# define DBG(text)
+#endif
+
+/* ----------------------------------------------------------- */
+/* Setup a set of screens */
+/* Screen data is used that best matches the requested parameters. */
+
+#include "screens.h" /* Pre-generated screen patterns */
+
+/* Screen a single color plane */
+void screen_thscreens( /* Pointer to dither function */
+ thscreens *t, /* Screening object pointer */
+ int width, int height, /* Width and height to screen in pixels */
+ int xoff, int yoff, /* Offset into screening pattern */
+ unsigned char *in, /* Input pixel buffer */
+ unsigned long ipitch, /* Increment between input lines */
+ unsigned char *out, /* Output pixel buffer */
+ unsigned long opitch /* Increment between output lines */
+) {
+ int i;
+ for (i = 0; i < t->np; i++)
+ t->sc[i]->screen(t->sc[i], width, height, xoff, yoff, in + 2 * i, t->np, ipitch,
+ out + i, t->np, opitch);
+}
+
+/* Delete a thscreens */
+void del_thscreens(thscreens *t) {
+ int i;
+
+ for (i = 0; i < t->np; i++)
+ t->sc[i]->del(t->sc[i]);
+ free(t->sc);
+ free(t);
+}
+
+/* Create a new thscreens object matching the parameters */
+thscreens *new_thscreens(
+ int exact, /* Return only exact matches */
+ int nplanes, /* Number of planes to screen */
+ double asp, /* Target aspect ratio (== dpiX/dpiY) */
+ int size, /* Target size */
+ sc_iencoding ie, /* Input encoding - must be scie_16 */
+ int oebpc, /* Output encoding bits per component - must be 8 */
+ int oelev, /* Output encoding levels. Must be <= 2 ^ oebpc */
+ int *oevalues, /* Optional output encoding values for each level */
+ /* Must be oelev entries. Default is 0 .. oelev-1 */
+ sc_oorder oo, /* Output bit ordering */
+ double overlap, /* Overlap between levels, 0 - 1.0 */
+ void **cntx, /* List of contexts for lookup table callback */
+ double (**lutfunc)(void *cntx, double in) /* List of callback function, NULL if none */
+) {
+ thscreens *t;
+ int i, bi = -1;
+ double bamatch; /* Best aspect match */
+ int bsize = 100000; /* Best size match */
+ int swap = 0; /* width and height will need swapping */
+
+ DBG(("thscreens: new called with:\n"));
+ DBG((" nplanes = 0x%x\n",nplanes));
+ DBG((" asp = %f\n",asp));
+ DBG((" ie = %d\n",ie));
+ DBG((" oebpc = %d\n",oebpc));
+ DBG((" oelev = %d\n",oelev));
+ DBG((" oo = %d\n",oo));
+ DBG((" overlap = %f\n",overlap));
+
+ if (asp < 1.0) { /* All screens[] have asp >= 1.0 */
+ asp = 1.0/asp;
+ swap = 1;
+ DBG(("thscreens: aspect swap needed\n"));
+ }
+
+ if ((t = (thscreens *)calloc(1, sizeof(thscreens))) == NULL) {
+ DBG(("thscreens: malloc of thscreens failed\n"));
+ return NULL;
+ }
+
+ t->np = nplanes; /* Number of planes */
+
+ DBG(("thscreens no planes = %d\n",t->np));
+
+ t->screen = screen_thscreens;
+ t->del = del_thscreens;
+
+ if ((t->sc = malloc(sizeof(thscreen *) * t->np)) == NULL) {
+ free(t);
+ DBG(("thscreens: malloc of thscreens->sc[] failed\n"));
+ return NULL;
+ }
+
+ DBG(("thscreens: searching amongst %d screens, exact = %d\n",NO_SCREENS,exact));
+
+ DBG(("thscreens: looking for non-exact match\n"));
+
+ /* Synthesise a set of screens from what's there */
+ /* (Don't bother with matching the colorspace) */
+ for (i = 0;i < NO_SCREENS; i++) {
+ double thamatch; /* This aspect match */
+ int thsize; /* This size match */
+
+ thamatch = asp/screens[i].asp;
+ if (thamatch < 1.0)
+ thamatch = 1.0/thamatch;
+
+ if (bi < 0 || (thamatch < bamatch)) { /* No best or new best */
+ bamatch = thamatch;
+ bi = i;
+ DBG(("thscreens: new best with aspmatch %f\n",bamatch));
+ continue; /* On to next */
+ }
+ if (thamatch > bamatch) /* Worse aspect match */
+ continue;
+ /* Same on aspect ratio. Check size */
+ thsize = size - screens[i].size;
+ if (thsize < 0)
+ thsize = -thsize;
+ if (thsize < bsize) { /* New better size match */
+ bsize = thsize;
+ bi = i;
+ DBG(("thscreens: new best with size %d\n",bsize));
+ }
+ }
+
+ if (bi < 0) /* Strange */
+ return NULL;
+
+ /* Create each screening object from one defined screen. */
+ /* Use the 0'th plane screen */
+ /* Stagger the screens with a round of 9 offset */
+ for (i = 0; i < t->np; i++) {
+ int xoff = ((i % 3) * screens[bi].width)/3;
+ int yoff = (((i/3) % 3) * screens[bi].height)/3;
+ void *cx = NULL;
+ double (*lf)(void *cntx, double in) = 0;
+ if (cntx != NULL)
+ cx = cntx[i];
+ if (lutfunc != NULL)
+ lf = lutfunc[i];
+
+ DBG(("thscreens: creating plane %d/%d thscreen, offset %d %d\n",i,t->np,xoff,yoff));
+ if ((t->sc[i] = new_thscreen(screens[bi].width, screens[bi].height, xoff, yoff,
+ screens[bi].asp, swap, screens[bi].list[0],
+ ie, oebpc, oelev, oevalues, oo, overlap,
+ cx, lf)) == NULL) {
+ for (--i; i >= 0; i--)
+ t->sc[i]->del(t->sc[i]);
+ free(t->sc);
+ free(t);
+ DBG(("thscreens: new_thscreen() failed\n"));
+ return NULL;
+ }
+ }
+ DBG(("thscreens: returning nonexact match\n"));
+ return t;
+}
+
+/* ----------------------------------------------------------- */
+/* The kernel screening routin */
+
+void thscreen16_8(
+ struct _thscreen *t, /* Screening object pointer */
+ int width, int height, /* Width and height to screen in pixels */
+ int xoff, int yoff, /* Offset into screening pattern (must be +ve) */
+ unsigned char *_in, /* Input pixel buffer */
+ unsigned long ipinc, /* Increment between input pixels */
+ unsigned long ipitch, /* Increment between input lines */
+ unsigned char *out, /* Output pixel buffer */
+ unsigned long opinc, /* Increment between output pixels */
+ unsigned long opitch /* Increment between output lines */
+) {
+ unsigned short *in = (unsigned short *)_in; /* Pointer to input pixel sized values */
+ int *lut = t->lut; /* Copy of 8 or 16 -> 16 bit lookup table */
+ unsigned char **oth, **eth; /* Current lines start, origin and end in screening table. */
+ int thtsize; /* Overall size of threshold table */
+ unsigned char **eeth; /* Very end of threshold table */
+ unsigned short *ein = in + height * ipitch; /* Vertical end pixel marker */
+ unsigned short *ein1; /* Horizontal end pixel markers */
+
+ {
+ unsigned char **sth; /* Start point of line intable */
+ sth = t->thp + (yoff % t->sheight) * t->twidth;
+ oth = sth + (xoff % t->swidth); /* Orgin of pattern to start from */
+ eth = sth + t->swidth; /* Ending point to wrap back */
+ thtsize = t->twidth * t->theight;
+ eeth = t->thp + thtsize; /* very end of table */
+ }
+
+ ein1 = in + ipinc * width;
+
+ /* For each line: */
+ for (; in < ein; in += ipitch, ein1 += ipitch, out += opitch) {
+ unsigned char **th = oth; /* Threshold table origin */
+ unsigned short *ip = in; /* Horizontal input pointer */
+ unsigned char *op = out; /* Horizontal output pointer */
+
+ /* Do pixels one output byte at a time */
+ for (; ip < ein1; ip += ipinc, op += opinc) {
+ int tt = lut[*ip];
+ *op = (unsigned char)th[0][tt];
+ if (++th >= eth)
+ th -= t->swidth;
+ }
+
+ /* Advance screen table pointers with vertical wrap */
+ oth += t->twidth;
+ eth += t->twidth;
+ if (eth > eeth) {
+ oth -= thtsize;
+ eth -= thtsize;
+ }
+ }
+}
+
+/* ----------------------------------------------------------- */
+
+/* We're done with the screening object */
+static void th_del(
+ thscreen *t
+) {
+ if (t->lut != NULL)
+ free(t->lut);
+ if (t->thp != NULL)
+ free(t->thp);
+ free(t);
+}
+
+/* Create a new thscreen object */
+/* Return NULL on error */
+thscreen *new_thscreen(
+ int width, /* width in pixels of screen */
+ int height, /* Height in pixels of screen */
+ int xoff, int yoff, /* Pattern offsets into width & height */
+ double asp, /* Aspect ratio of screen (== dpiX/dpiY) */
+ int swap, /* Swap X & Y to invert aspect ratio & swap width/height */
+ ccoord *thli, /* Pointer to list of threshold coordinates */
+ sc_iencoding ie, /* Input encoding - must be scie_16 */
+ int oebpc, /* Output encoding bits per component - must be 8 */
+ int oelev, /* Output encoding levels. Must be <= 2 ^ oebpc */
+ int *oevalues, /* Optional output encoding values for each level */
+ /* Must be oelev entries. Default is 0 .. oelev-1 */
+ sc_oorder oo, /* Output bit ordering */
+ double olap, /* Overlap between levels, 0 - 1.0 */
+ void *cntx, /* Context for LUT table callback */
+ double (*lutfunc)(void *cntx, double in) /* Callback function, NULL if none */
+) {
+ thscreen *t; /* Object being created */
+ int npix; /* Total pixels in screen */
+ double mrang; /* threshold modulation range */
+ double **fthr; /* Floating point threshold array */
+ int i, j;
+
+ DBG(("new_thscreen() called, oebpc = %d\n",oebpc));
+ DBG(("new_thscreen() called, oelev = %d\n",oelev));
+
+ /* Sanity check overlap */
+ if (olap < 0.0)
+ olap = 0.0;
+ else if (olap > 1.0)
+ olap = 1.0;
+
+ /* Sanity check parameters */
+ if (ie != scie_16) {
+ DBG(("new_thscreen() ie %d != scie_16\n",ie));
+ return NULL;
+ }
+ if (oebpc != 8) {
+ DBG(("new_thscreen() oebpc %d != 8\n",oebpc));
+ return NULL;
+ }
+
+ if (oelev < 2 || oelev > (1 << oebpc)) {
+ DBG(("new_thscreen() oelev %d > 2^%d = %d\n",oelev,1 << oebpc,oebpc));
+ return NULL;
+ }
+
+ if ((t = (thscreen *)calloc(1, sizeof(thscreen))) == NULL) {
+ DBG(("new_thscreen() calloc failed\n"));
+ return NULL;
+ }
+
+ /* Instantiation parameters */
+ t->ie = ie;
+ t->oebpc = oebpc;
+ t->oelev = oelev;
+ if (oevalues != NULL) {
+ for (i = 0; i < t->oelev; i++) {
+ if (oevalues[i] >= (1 << t->oebpc)) {
+ DBG(("new_thscreen() oevalues[%d] value %d can't fit in %d bits\n",i,oevalues[i],t->oebpc));
+ free(t);
+ return NULL;
+ }
+ t->oevalues[i] = oevalues[i];
+ }
+ } else {
+ for (i = 0; i < t->oelev; i++)
+ t->oevalues[i] = i;
+ }
+
+ t->oo = oo;
+ t->overlap = olap;
+
+ /* Create a suitable LUT from the given function */
+ /* Input is either 8 or 16 bits, output is always 16 bits */
+ DBG(("new_thscreen() about to create LUT\n"));
+ if ((t->lut = (int *)malloc(sizeof(int) * 65536)) == NULL) {
+ free(t);
+ DBG(("new_thscreen() malloc of 16 bit LUT failed\n"));
+ return NULL;
+ }
+ for (i = 0; i < 65536; i++) {
+ if (lutfunc != NULL) {
+ double v = i/65535.0;
+ v = lutfunc(cntx, v);
+ t->lut[i] = (int)(v * 65535.0 + 0.5);
+ } else
+ t->lut[i] = i;
+ }
+
+ /* Screen definition parameters */
+ if (swap) {
+ t->asp = 1.0/asp;
+ t->swidth = height;
+ t->sheight = width;
+ } else {
+ t->asp = asp;
+ t->swidth = width;
+ t->sheight = height;
+ }
+ DBG(("new_thscreen() target width %d, height %d, asp %f\n",t->swidth,t->sheight,t->asp));
+ DBG(("new_thscreen() given width %d, height %d, asp %f\n",width,height,asp));
+
+ npix = t->swidth * t->sheight; /* Total pixels */
+ /* Allow for read of a words worth of pixels from within screen: */
+ DBG(("new_thscreen() tot pix %d, lev %d, bpp %d\n",npix,t->oelev,t->oebpc));
+
+ t->twidth = t->swidth + (8/t->oebpc) -1;
+ t->theight = t->sheight;
+
+ DBG(("new_thscreen() th table size = %d x %d\n",t->twidth,t->theight));
+ DBG(("new_thscreen() about to turn screen list into float threshold matrix\n"));
+
+ /* Convert the list of screen cells into a floating point threshold array */
+ fthr = dmatrix(0, t->sheight-1, 0, t->swidth-1); /* Temporary matrix */
+ if (swap) {
+ double tt = xoff; /* Swap offsets to align with orientation */
+ xoff = yoff;
+ yoff = tt;
+ for (i = 0; i < npix; i++)
+ fthr[thli[i].x][thli[i].y] = (double)(i/(npix - 1.0));
+ } else {
+ for (i = 0; i < npix; i++)
+ fthr[thli[i].y][thli[i].x] = (double)(i/(npix - 1.0));
+ }
+
+ /* The range that the screen has to modulate */
+ /* over to cross all the thresholds evenly. */
+ mrang = 65535.0/(t->oelev - 1.0);
+ DBG(("new_thscreen() raw modulation rande = %f\n",mrang));
+
+ /* Modify the modulation range to accomodate any level overlap */
+ if (olap > 0.0 && t->oelev > 2) {
+ mrang = ((t->oelev - 2.0) * olap * mrang + 65535.0)/(t->oelev - 1.0);
+ DBG(("new_thscreen() modulation adjusted for overlap = %f\n",mrang));
+ }
+
+ /* Init the threshold table. It holds the quantized, encoded output */
+ /* values, allowing an input value offset by the screen to be */
+ /* thresholded directly into the output value. We allow a guard band at */
+ /* each end for the effects of the screen modulating the input value. */
+
+ DBG(("new_thscreen() about to init threshold table\n"));
+ t->tht = &t->_tht[32768]; /* base allows for -ve & +ve range */
+ for (i = -32768; i < (2 * 65536) + 32768; i++) {
+ if (i < mrang) { /* Lower guard band */
+ t->tht[i] = t->oevalues[0];
+ } else if (i >= 65535) { /* Upper guard band */
+ t->tht[i] = t->oevalues[t->oelev-1];
+ } else { /* Middle range */
+ t->tht[i] = t->oevalues[1 + (int)((t->oelev - 2.0) * (i - mrang)/(65535.0 - mrang))];
+ }
+ }
+
+ /* Allocate the 2D table of pointers into the */
+ /* threshold table that encodes the screen offset. */
+ if ((t->thp = (unsigned char **)malloc(sizeof(unsigned char *)
+ * t->twidth * t->theight)) == NULL) {
+ free_dmatrix(fthr, 0, t->sheight-1, 0, t->swidth-1);
+ free(t->lut);
+ free(t);
+ DBG(("new_thscreen() malloc of threshold pointer matrix failed\n"));
+ return NULL;
+ }
+
+ /* Setup the threshold pointer array to point into the apropriate */
+ /* point into the threshold array itself. This implicitly adds */
+ /* the screen pattern offset value to the input before thresholding it. */
+ /* The input screen offsets are applied at this point too. */
+ DBG(("new_thscreen() about to init threshold pointer table\n"));
+ for (i = 0; i < t->twidth; i++) {
+ for (j = 0; j < t->theight; j++) {
+ double sov = fthr[(j+yoff) % t->sheight][(i+xoff) % t->swidth];
+ int tho = (int)((mrang - 1.0) * (1.0 - sov) + 0.5);
+ t->thp[j * t->twidth + i] = &t->tht[tho];
+ }
+ }
+ free_dmatrix(fthr, 0, t->sheight-1, 0, t->swidth-1);
+
+ DBG(("new_thscreen() about to setup method pointers\n"));
+
+ /* Methods */
+ t->screen = thscreen16_8;
+ t->del = th_del;
+
+ DBG(("new_thscreen() done\n"));
+ return t;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/render/thscreen.h b/render/thscreen.h
new file mode 100644
index 0000000..d3ac9b1
--- /dev/null
+++ b/render/thscreen.h
@@ -0,0 +1,156 @@
+
+#ifndef THSCREEN_H
+#define THSCREEN_H
+
+/*
+ * render2d
+ *
+ * Threshold screen pixel processing object.
+ * (Simplified from DPS code)
+ *
+ * Author: Graeme W. Gill
+ * Date: 11/7/2005
+ * Version: 1.00
+ *
+ * Copyright 2005, 2012 Graeme W. Gill
+ * All rights reserved.
+ * This material is licenced under the GNU AFFERO GENERAL PUBLIC LICENSE Version 3 :-
+ * see the License.txt file for licencing details.
+ *
+ */
+
+/* Light Separation in screening flag */
+typedef enum {
+ scls_false = 0, /* Don't do light ink separation during screening. */
+ scls_true = 0 /* Do light ink separation during screening. */
+} sc_lightsep;
+
+/* Input encoding */
+typedef enum {
+ scie_8 = 0, /* 8 bit per component */
+ scie_16 = 1 /* 16 bit per component */
+} sc_iencoding;
+
+/* Output bit order within byte */
+typedef enum {
+ scoo_l = 0, /* Little endian */
+ scoo_b = 1 /* Big endian */
+} sc_oorder;
+
+
+/* ---------------------------- */
+/* Setup a set of screens */
+
+struct _thscreens {
+ int np; /* Number of planes */
+ struct _thscreen **sc; /* List of screens */
+
+ /* Screen a single color plane */
+ void (* screen)( /* Pointer to dither function */
+ struct _thscreens *t, /* Screening object pointer */
+ int width, int height, /* Width and height to screen in pixels */
+ int xoff, int yoff, /* Offset into screening pattern */
+ unsigned char *in, /* Input pixel buffer */
+ unsigned long ipitch, /* Increment between input lines */
+ unsigned char *out, /* Output pixel buffer */
+ unsigned long opitch); /* Increment between output lines */
+
+ void (* del)( /* Destructor */
+ struct _thscreens *t); /* Screening objects pointer */
+
+}; typedef struct _thscreens thscreens;
+
+
+/* Return a thscreens object */
+/* Screen data is used that best matches the requested parameters. */
+/* Return NULL on error */
+thscreens *new_thscreens(
+ int exact, /* Return only exact matches */
+ int nplanes, /* Number of planes to screen */
+ double asp, /* Target aspect ratio (== dpiX/dpiY) */
+ int size, /* Target size */
+ sc_iencoding ie, /* Input encoding - must be scie_16 */
+ int oebpc, /* Output encoding bits per component - must be 8 */
+ int oelev, /* Output encoding levels. Must be <= 2 ^ oebpc */
+ int *oevalues, /* Optional output encoding values for each level */
+ /* Must be oelev entries. Default is 0 .. oelev-1 */
+ sc_oorder oo, /* Output bit ordering */
+ double overlap, /* Overlap between levels, 0 - 1.0 */
+ void **cntx, /* List of contexts for lookup table callback */
+ double (**lutfunc)(void *cntx, double in) /* List of callback function, NULL if none */
+);
+
+/* ---------------------------- */
+/* Screen defintion information */
+
+typedef struct {
+ int x;
+ int y;
+} ccoord;
+
+typedef struct {
+ int size; /* General size */
+ int width; /* width in pixels */
+ int height; /* Height in pixels */
+ double asp; /* Aspect ratio (== dpiX/dpiY) */
+ int joint; /* na for joint screens */
+ ccoord **list; /* Pointer to list of pointers to threshold coordinates */
+} thscdef;
+
+/* ------------------------ */
+/* Setup of a single screen */
+
+struct _thscreen {
+ sc_iencoding ie; /* Input encoding */
+ int oebpc; /* Output encoding bits per component, 1,2,4 or 8 */
+ int oelev; /* Output encoding levels. Must be <= 2 ^ oebpc */
+ int oevalues[256]; /* Output encoding values for each level */
+ sc_oorder oo; /* Output bit ordering */
+ double asp; /* Aspect ratio (== dpiX/dpiY) */
+ double overlap; /* Overlap between levels, 0 - 1.0 */
+ int *lut; /* Lookup table */
+ unsigned char _tht[65536 * 3];/* Threshold table */
+ unsigned char *tht; /* Pointer to base of threshold table */
+ unsigned char **thp; /* Pointers to threshold table (offset int _tht) */
+ int swidth; /* Given screen width */
+ int sheight; /* Given screen height */
+ int twidth; /* Rounded up screen table width & stride */
+ int theight; /* Screen table height */
+
+ void (* screen)( /* Pointer to dither function */
+ struct _thscreen *t, /* Screening object pointer */
+ int width, int height, /* Width and height to screen in pixels */
+ int xoff, int yoff, /* Offset into screening pattern */
+ unsigned char *in, /* Input pixel buffer */
+ unsigned long ipinc, /* Increment between input pixels */
+ unsigned long ipitch, /* Increment between input lines */
+ unsigned char *out, /* Output pixel buffer */
+ unsigned long opinc, /* Increment between output pixels */
+ unsigned long opitch); /* Increment between output lines */
+
+ void (* del)( /* Destructor */
+ struct _thscreen *t); /* Screening object pointer */
+
+}; typedef struct _thscreen thscreen;
+
+/* Create a new thscreen object */
+/* Return NULL on error */
+thscreen *new_thscreen(
+ int width, /* width in pixels */
+ int height, /* Height in pixels */
+ int xoff, int yoff, /* Pattern offsets into width & height (must be +ve) */
+ double asp, /* Aspect ratio (== dpiX/dpiY) */
+ int swap, /* Swap X & Y to invert aspect ratio */
+ ccoord *thli, /* List of screen initialisation threshold coordinates */
+ sc_iencoding ie, /* Input encoding - must be scie_16 */
+ int oebpc, /* Output encoding bits per component - must be 8 */
+ int oelev, /* Output encoding levels. Must be <= 2 ^ oebpc */
+ int *oevalues, /* Optional output encoding values for each level */
+ /* Must be oelev entries. Default is 0 .. oelev-1 */
+ sc_oorder oo, /* Output bit ordering */
+ double olap, /* Overlap between levels, 0 - 1.0 */
+ void *cntx, /* Context for LUT table callback */
+ double (*lutfunc)(void *cntx, double in) /* Callback function, NULL if none */
+);
+
+#endif /* THSCREEN_H */
diff --git a/render/timage.c b/render/timage.c
new file mode 100644
index 0000000..c4404f7
--- /dev/null
+++ b/render/timage.c
@@ -0,0 +1,682 @@
+
+/*
+ * Argyll Color Correction System
+ *
+ * RGB gamut boundary test image generator
+ *
+ * Author: Graeme W. Gill
+ * Date: 28/12/2005
+ *
+ * Copyright 2005 Graeme W. Gill
+ * All rights reserved.
+ *
+ * This material is licenced under the GNU AFFERO GENERAL PUBLIC LICENSE Version 3 :-
+ * see the License.txt file for licencing details.
+ */
+
+/*
+ * Generate TIFF image with two RGB cube surface hexagons,
+ * plus a rectangular grey wedges between them, on a grey
+ * background, or a rectangular gamut surface test image.
+ */
+
+/*
+ * TTBD:
+ */
+
+#undef DEBUG
+
+#define verbo stdout
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include "copyright.h"
+#include "aconfig.h"
+#include "numsup.h"
+#include "render.h"
+
+#define DEF_DPI 200
+#define DITHER 0 /* Test 8 bit didthering */
+
+void
+usage(void) {
+ fprintf(stderr,"Create test images, default hex RGB surface and wedge, Version %s\n",ARGYLL_VERSION_STR);
+ fprintf(stderr,"Author: Graeme W. Gill, licensed under the AGPL Version 3\n");
+ fprintf(stderr,"usage: timage [-options] outfile.tif\n");
+// fprintf(stderr," -v Verbose\n");
+ fprintf(stderr," -t Generate rectangular gamut boundary test chart\n");
+ fprintf(stderr," -p steps Generate a colorspace step chart with L* steps^2\n");
+ fprintf(stderr," -r res Resolution in DPI (default %d)\n",DEF_DPI);
+ fprintf(stderr," -s Smooth blend\n");
+ fprintf(stderr," -x 16 bit output\n");
+ fprintf(stderr," -4 CMYK output\n");
+ fprintf(stderr," -g prop Percentage towards grey (default 0%%)\n");
+// fprintf(stderr," -D Debug primitives plot */
+ fprintf(stderr," outfile.tif Profile to check against\n");
+ exit(1);
+ }
+
+int main(int argc, char *argv[])
+{
+ int fa,nfa; /* current argument we're looking at */
+ int verb = 0;
+ int rchart = 0; /* Rectangular chart */
+ int schart = 0; /* Step chart with steps^2 */
+ int smooth = 0; /* Use smooth blending */
+ int debugchart = 0; /* Debug chart */
+ double res = DEF_DPI;
+ depth2d depth = bpc8_2d;
+ int cmyk = 0; /* Do CMYK output */
+ char outname[MAXNAMEL+1] = { 0 }; /* Output TIFF name */
+ render2d *r;
+ color2d c;
+ double vv[4][2];
+ color2d cc[4];
+ double gbf = 1.0; /* Grey blend factor */
+ double w, h; /* Size of page in mm */
+ int i, j;
+
+ error_program = "timage";
+
+ if (argc <= 1)
+ usage();
+
+ /* Process the arguments */
+ for(fa = 1;fa < argc;fa++) {
+
+ nfa = fa; /* skip to nfa if next argument is used */
+ if (argv[fa][0] == '-') { /* Look for any flags */
+ char *na = NULL; /* next argument after flag, null if none */
+
+ if (argv[fa][2] != '\000')
+ na = &argv[fa][2]; /* next is directly after flag */
+ else {
+ if ((fa+1) < argc) {
+ if (argv[fa+1][0] != '-') {
+ nfa = fa + 1;
+ na = argv[nfa]; /* next is seperate non-flag argument */
+ }
+ }
+ }
+
+ if (argv[fa][1] == '?')
+ usage();
+
+ else if (argv[fa][1] == 'v' || argv[fa][1] == 'V')
+ verb = 1;
+
+ /* Rectangular chart */
+ else if (argv[fa][1] == 't' || argv[fa][1] == 'T') {
+ rchart = 1;
+ schart = 0;
+
+ /* Smooth blending */
+ } else if (argv[fa][1] == 's' || argv[fa][1] == 'S')
+ smooth = 1;
+
+ /* 16 bit depth */
+ else if (argv[fa][1] == 'x' || argv[fa][1] == 'X')
+ depth = bpc16_2d;
+
+ /* cmyk */
+ else if (argv[fa][1] == '4')
+ cmyk = 1;
+
+ /* step chart */
+ else if (argv[fa][1] == 'p' || argv[fa][1] == 'P') {
+ fa = nfa;
+ if (na == NULL) usage();
+ schart = atoi(na);
+ if (schart <= 0) usage();
+ rchart = 0;
+ }
+
+ /* debug chart */
+ else if (argv[fa][1] == 'D') {
+ debugchart = 1;
+ }
+
+ /* resolution */
+ else if (argv[fa][1] == 'r' || argv[fa][1] == 'R') {
+ fa = nfa;
+ if (na == NULL) usage();
+ res = atof(na);
+ if (res <= 0.0) usage();
+ }
+
+ /* grey blend */
+ else if (argv[fa][1] == 'g' || argv[fa][1] == 'G') {
+ fa = nfa;
+ if (na == NULL) usage();
+ gbf = 1.0 - 0.01 * atof(na);
+ if (gbf < 0.0 || gbf > 1.0) usage();
+ }
+ else
+ usage();
+ } else
+ break;
+ }
+
+ /* Get the file name arguments */
+ if (fa >= argc || argv[fa][0] == '-') usage();
+ strncpy(outname,argv[fa++],MAXNAMEL); outname[MAXNAMEL] = '\000';
+
+ res /= 25.4; /* Convert to DPmm */
+
+ /* Debug chart - test each primitive in RGB space */
+ if (debugchart) {
+ font2d fo;
+
+ h = 140.0;
+ w = 200.0;
+
+ if (cmyk)
+ error("CMYK not supported for test chart");
+
+ if ((r = new_render2d(w, h, NULL, res, res, rgb_2d, 0, depth, DITHER)) == NULL) {
+ error("new_render2d() failed");
+ }
+
+ /* Set the background color */
+// c[0] = 0.5;
+// c[1] = 0.5;
+// c[2] = 0.5;
+ c[0] = 1.0;
+ c[1] = 1.0;
+ c[2] = 1.0;
+ r->set_defc(r, c);
+
+ c[0] = 1.0; /* Red rectangle, bottom left */
+ c[1] = 0.0;
+ c[2] = 0.0;
+ r->add(r, new_rect2d(r, 5.0, 5.0, 8.0, 8.0, c)) ;
+
+ c[0] = 0.0; /* Green to the right of red */
+ c[1] = 1.0;
+ c[2] = 0.0;
+ r->add(r, new_rect2d(r, 15.0, 5.0, 8.0, 8.0, c)) ;
+
+ c[0] = 0.0; /* Blue to the right of green */
+ c[1] = 0.0;
+ c[2] = 1.0;
+ r->add(r, new_rect2d(r, 25.0, 5.0, 8.0, 8.0, c)) ;
+
+ /* A vertex shaded rectangle */
+ cc[0][0] = 1.0; /* Red */
+ cc[0][1] = 0.0;
+ cc[0][2] = 0.0;
+ cc[1][0] = 0.0; /* Green */
+ cc[1][1] = 1.0;
+ cc[1][2] = 0.0;
+ cc[2][0] = 0.0; /* Blue */
+ cc[2][1] = 0.0;
+ cc[2][2] = 1.0;
+ cc[3][0] = 1.0; /* Yellow */
+ cc[3][1] = 1.0;
+ cc[3][2] = 0.0;
+
+ r->add(r, new_rectvs2d(r, 5.0, 20.0, 18.0, 18.0, cc));
+
+ /* A shaded triangle to the right of the shaded rectangle */
+ vv[0][0] = 30.0;
+ vv[0][1] = 20.0;
+ cc[0][0] = 0.0;
+ cc[0][1] = 1.0;
+ cc[0][2] = 1.0;
+
+ vv[1][0] = 50.0;
+ vv[1][1] = 20.0;
+ cc[1][0] = 1.0;
+ cc[1][1] = 0.0;
+ cc[1][2] = 1.0;
+
+ vv[2][0] = 40.0;
+ vv[2][1] = 40.0;
+ cc[2][0] = 1.0;
+ cc[2][1] = 1.0;
+ cc[2][2] = 0.0;
+ r->add(r, new_trivs2d(r, vv, cc));
+
+ /* A diagonal wide line */
+ c[0] = 0.0;
+ c[1] = 0.0;
+ c[2] = 0.0;
+ r->add(r, new_line2d(r, 10.0, 45.0, 11.0, 55.0, 3.0, 1, c));
+
+ /* A dashed line */
+ add_dashed_line2d(r, 20.0, 45.0, 100.0, 65.0, 1.0, 3.0, 5.0, 1, c);
+
+ fo = futura_l;
+
+ /* rectange the size the letter A should be */
+ c[0] = 0.7;
+ c[1] = 0.0;
+ c[2] = 0.0;
+ r->add(r, new_rect2d(r, 10.0, 60.0, 7.7, 10.0, c)) ;
+
+ c[0] = 0.0;
+ c[1] = 0.0;
+ c[2] = 0.0;
+ /* The letter A */
+ add_char2d(r, NULL, NULL, fo, 'A', 10.0, 60.0, 10.0, 0, c);
+
+ /* A test string */
+ add_string2d(r, NULL, NULL, fo, "Testing 1234", 10.0, 70.0, 7.0, 3, c);
+
+ {
+ double x, y;
+ char chars[33];
+
+ x = 10.0;
+ y = 125.0;
+ for (j = 0; j < 4; j++) {
+ for (i = 0; i < 32; i++)
+ chars[i] = j * 32 + i;
+ chars[i] = '\000';
+ add_string2d(r, NULL, NULL, fo, chars, x, y, 7.0, 0, c);
+ y -= 10.0;
+ }
+ }
+
+ /* RGB Hexagon chart */
+ } else if (rchart == 0 && schart == 0) {
+ double r3o2; /* 0.866025 */
+ double bb = 0.07; /* Border proportion */
+ double hh = 40.0; /* Height of hexagon in mm */
+ color2d white;
+ color2d red;
+ color2d green;
+ color2d blue;
+ color2d cyan;
+ color2d magenta;
+ color2d yellow;
+ color2d black;
+ color2d grey;
+ color2d kblack;
+
+ r3o2 = sqrt(3.0)/2.0; /* Width to heigh of hexagon */
+ h = (1.0 + 2.0 * bb) * hh;
+ w = (4.0 * bb + 0.25 + 2.0 * r3o2) * hh;
+
+ if ((r = new_render2d(w, h, NULL, res, res, cmyk ? cmyk_2d : rgb_2d, 0, depth, DITHER)) == NULL) {
+ error("new_render2d() failed");
+ }
+
+ if (cmyk) {
+ white[0] = 0.0;
+ white[1] = 0.0;
+ white[2] = 0.0;
+ white[3] = 0.0;
+ red[0] = 0.0;
+ red[1] = 1.0;
+ red[2] = 1.0;
+ red[3] = 0.0;
+ green[0] = 1.0;
+ green[1] = 0.0;
+ green[2] = 1.0;
+ green[3] = 0.0;
+ blue[0] = 1.0;
+ blue[1] = 1.0;
+ blue[2] = 0.0;
+ blue[3] = 0.0;
+ cyan[0] = 1.0;
+ cyan[1] = 0.0;
+ cyan[2] = 0.0;
+ cyan[3] = 0.0;
+ magenta[0] = 0.0;
+ magenta[1] = 1.0;
+ magenta[2] = 0.0;
+ magenta[3] = 0.0;
+ yellow[0] = 0.0;
+ yellow[1] = 0.0;
+ yellow[2] = 1.0;
+ yellow[3] = 0.0;
+ kblack[0] = 0.0;
+ kblack[1] = 0.0;
+ kblack[2] = 0.0;
+ kblack[3] = 1.0;
+ grey[0] = 0.0;
+ grey[1] = 0.0;
+ grey[2] = 0.0;
+ grey[3] = 0.5;
+ black[0] = 1.0;
+ black[1] = 1.0;
+ black[2] = 1.0;
+ black[3] = 0.0;
+ } else {
+ white[0] = 1.0;
+ white[1] = 1.0;
+ white[2] = 1.0;
+ red[0] = 1.0;
+ red[1] = 0.0;
+ red[2] = 0.0;
+ green[0] = 0.0;
+ green[1] = 1.0;
+ green[2] = 0.0;
+ blue[0] = 0.0;
+ blue[1] = 0.0;
+ blue[2] = 1.0;
+ cyan[0] = 0.0;
+ cyan[1] = 1.0;
+ cyan[2] = 1.0;
+ magenta[0] = 1.0;
+ magenta[1] = 0.0;
+ magenta[2] = 1.0;
+ yellow[0] = 1.0;
+ yellow[1] = 1.0;
+ yellow[2] = 0.0;
+ black[0] = 0.0;
+ black[1] = 0.0;
+ black[2] = 0.0;
+ grey[0] = 0.5;
+ grey[1] = 0.5;
+ grey[2] = 0.5;
+ }
+
+ /* Set the default color */
+ r->set_defc(r, grey);
+
+ /* Left hand hex */
+ vv[0][0] = hh * bb + r3o2 * 0.5 * hh;
+ vv[0][1] = hh * bb + hh/2.0;
+ cc[0][0] = white[0] * gbf + (1.0 - gbf) * grey[0];
+ cc[0][1] = white[1] * gbf + (1.0 - gbf) * grey[1];
+ cc[0][2] = white[2] * gbf + (1.0 - gbf) * grey[2];
+ cc[0][3] = white[3] * gbf + (1.0 - gbf) * grey[3];
+
+ vv[1][0] = hh * bb + r3o2 * 0.5 * hh;
+ vv[1][1] = hh * bb;
+ cc[1][0] = red[0] * gbf + (1.0 - gbf) * grey[0];
+ cc[1][1] = red[1] * gbf + (1.0 - gbf) * grey[1];
+ cc[1][2] = red[2] * gbf + (1.0 - gbf) * grey[2];
+ cc[1][3] = red[3] * gbf + (1.0 - gbf) * grey[3];
+
+ vv[2][0] = hh * bb;
+ vv[2][1] = hh * bb + 0.25 * hh;
+ cc[2][0] = magenta[0] * gbf + (1.0 - gbf) * grey[0];
+ cc[2][1] = magenta[1] * gbf + (1.0 - gbf) * grey[1];
+ cc[2][2] = magenta[2] * gbf + (1.0 - gbf) * grey[2];
+ cc[2][3] = magenta[3] * gbf + (1.0 - gbf) * grey[3];
+ r->add(r, new_trivs2d(r, vv, cc));
+
+ vv[1][0] = hh * bb;
+ vv[1][1] = hh * bb + 0.75 * hh;
+ cc[1][0] = blue[0] * gbf + (1.0 - gbf) * grey[0];
+ cc[1][1] = blue[1] * gbf + (1.0 - gbf) * grey[1];
+ cc[1][2] = blue[2] * gbf + (1.0 - gbf) * grey[2];
+ cc[1][3] = blue[3] * gbf + (1.0 - gbf) * grey[3];
+ r->add(r, new_trivs2d(r, vv, cc));
+
+ vv[2][0] = hh * bb + r3o2 * 0.5 * hh;
+ vv[2][1] = hh * bb + 1.0 * hh;
+ cc[2][0] = cyan[0] * gbf + (1.0 - gbf) * grey[0];
+ cc[2][1] = cyan[1] * gbf + (1.0 - gbf) * grey[1];
+ cc[2][2] = cyan[2] * gbf + (1.0 - gbf) * grey[2];
+ cc[2][3] = cyan[3] * gbf + (1.0 - gbf) * grey[3];
+ r->add(r, new_trivs2d(r, vv, cc));
+
+ vv[1][0] = hh * bb + r3o2 * 1.0 * hh;;
+ vv[1][1] = hh * bb + 0.75 * hh;
+ cc[1][0] = green[0] * gbf + (1.0 - gbf) * grey[0];
+ cc[1][1] = green[1] * gbf + (1.0 - gbf) * grey[1];
+ cc[1][2] = green[2] * gbf + (1.0 - gbf) * grey[2];
+ cc[1][3] = green[3] * gbf + (1.0 - gbf) * grey[3];
+ r->add(r, new_trivs2d(r, vv, cc));
+
+ vv[2][0] = hh * bb + r3o2 * 1.0 * hh;
+ vv[2][1] = hh * bb + 0.25 * hh;
+ cc[2][0] = yellow[0] * gbf + (1.0 - gbf) * grey[0];
+ cc[2][1] = yellow[1] * gbf + (1.0 - gbf) * grey[1];
+ cc[2][2] = yellow[2] * gbf + (1.0 - gbf) * grey[2];
+ cc[2][3] = yellow[3] * gbf + (1.0 - gbf) * grey[3];
+ r->add(r, new_trivs2d(r, vv, cc));
+
+ vv[1][0] = hh * bb + r3o2 * 0.5 * hh;;
+ vv[1][1] = hh * bb;
+ cc[1][0] = red[0] * gbf + (1.0 - gbf) * grey[0];
+ cc[1][1] = red[1] * gbf + (1.0 - gbf) * grey[1];
+ cc[1][2] = red[2] * gbf + (1.0 - gbf) * grey[2];
+ cc[1][3] = red[3] * gbf + (1.0 - gbf) * grey[3];
+ r->add(r, new_trivs2d(r, vv, cc));
+
+
+ /* Right hand hex */
+ vv[0][0] = hh * (3.0 * bb + 0.25 + r3o2) + r3o2 * 0.5 * hh;
+ vv[0][1] = hh * bb + hh/2.0;
+ cc[0][0] = black[0] * gbf + (1.0 - gbf) * grey[0];
+ cc[0][1] = black[1] * gbf + (1.0 - gbf) * grey[1];
+ cc[0][2] = black[2] * gbf + (1.0 - gbf) * grey[2];
+ cc[0][3] = black[3] * gbf + (1.0 - gbf) * grey[3];
+
+ vv[1][0] = hh * (3.0 * bb + 0.25 + r3o2) + r3o2 * 0.5 * hh;
+ vv[1][1] = hh * bb;
+ cc[1][0] = red[0] * gbf + (1.0 - gbf) * grey[0];
+ cc[1][1] = red[1] * gbf + (1.0 - gbf) * grey[1];
+ cc[1][2] = red[2] * gbf + (1.0 - gbf) * grey[2];
+ cc[1][3] = red[3] * gbf + (1.0 - gbf) * grey[3];
+
+ vv[2][0] = hh * (3.0 * bb + 0.25 + r3o2);
+ vv[2][1] = hh * bb + 0.25 * hh;
+ cc[2][0] = magenta[0] * gbf + (1.0 - gbf) * grey[0];
+ cc[2][1] = magenta[1] * gbf + (1.0 - gbf) * grey[1];
+ cc[2][2] = magenta[2] * gbf + (1.0 - gbf) * grey[2];
+ cc[2][3] = magenta[3] * gbf + (1.0 - gbf) * grey[3];
+ r->add(r, new_trivs2d(r, vv, cc));
+
+ vv[1][0] = hh * (3.0 * bb + 0.25 + r3o2);
+ vv[1][1] = hh * bb + 0.75 * hh;
+ cc[1][0] = blue[0] * gbf + (1.0 - gbf) * grey[0];
+ cc[1][1] = blue[1] * gbf + (1.0 - gbf) * grey[1];
+ cc[1][2] = blue[2] * gbf + (1.0 - gbf) * grey[2];
+ cc[1][3] = blue[3] * gbf + (1.0 - gbf) * grey[3];
+ r->add(r, new_trivs2d(r, vv, cc));
+
+ vv[2][0] = hh * (3.0 * bb + 0.25 + r3o2) + r3o2 * 0.5 * hh;
+ vv[2][1] = hh * bb + 1.0 * hh;
+ cc[2][0] = cyan[0] * gbf + (1.0 - gbf) * grey[0];
+ cc[2][1] = cyan[1] * gbf + (1.0 - gbf) * grey[1];
+ cc[2][2] = cyan[2] * gbf + (1.0 - gbf) * grey[2];
+ cc[1][3] = cyan[3] * gbf + (1.0 - gbf) * grey[3];
+ r->add(r, new_trivs2d(r, vv, cc));
+
+ vv[1][0] = hh * (3.0 * bb + 0.25 + r3o2) + r3o2 * 1.0 * hh;;
+ vv[1][1] = hh * bb + 0.75 * hh;
+ cc[1][0] = green[0] * gbf + (1.0 - gbf) * grey[0];
+ cc[1][1] = green[1] * gbf + (1.0 - gbf) * grey[1];
+ cc[1][2] = green[2] * gbf + (1.0 - gbf) * grey[2];
+ cc[1][3] = green[3] * gbf + (1.0 - gbf) * grey[3];
+ r->add(r, new_trivs2d(r, vv, cc));
+
+ vv[2][0] = hh * (3.0 * bb + 0.25 + r3o2) + r3o2 * 1.0 * hh;
+ vv[2][1] = hh * bb + 0.25 * hh;
+ cc[2][0] = yellow[0] * gbf + (1.0 - gbf) * grey[0];
+ cc[2][1] = yellow[1] * gbf + (1.0 - gbf) * grey[1];
+ cc[2][2] = yellow[2] * gbf + (1.0 - gbf) * grey[2];
+ cc[2][3] = yellow[3] * gbf + (1.0 - gbf) * grey[3];
+ r->add(r, new_trivs2d(r, vv, cc));
+
+ vv[1][0] = hh * (3.0 * bb + 0.25 + r3o2) + r3o2 * 0.5 * hh;;
+ vv[1][1] = hh * bb;
+ cc[1][0] = red[0] * gbf + (1.0 - gbf) * grey[0];
+ cc[1][1] = red[1] * gbf + (1.0 - gbf) * grey[1];
+ cc[1][2] = red[2] * gbf + (1.0 - gbf) * grey[2];
+ cc[1][3] = red[3] * gbf + (1.0 - gbf) * grey[3];
+ r->add(r, new_trivs2d(r, vv, cc));
+
+ /* Center wedge */
+ cc[0][0] = black[0] * gbf + (1.0 - gbf) * grey[0];
+ cc[0][1] = black[1] * gbf + (1.0 - gbf) * grey[1];
+ cc[0][2] = black[2] * gbf + (1.0 - gbf) * grey[2];
+ cc[0][3] = black[3] * gbf + (1.0 - gbf) * grey[3];
+ cc[1][0] = black[0] * gbf + (1.0 - gbf) * grey[0];
+ cc[1][1] = black[1] * gbf + (1.0 - gbf) * grey[1];
+ cc[1][2] = black[2] * gbf + (1.0 - gbf) * grey[2];
+ cc[1][3] = black[3] * gbf + (1.0 - gbf) * grey[3];
+ cc[2][0] = white[0] * gbf + (1.0 - gbf) * grey[0];
+ cc[2][1] = white[1] * gbf + (1.0 - gbf) * grey[1];
+ cc[2][2] = white[2] * gbf + (1.0 - gbf) * grey[2];
+ cc[2][3] = white[3] * gbf + (1.0 - gbf) * grey[3];
+ cc[3][0] = white[0] * gbf + (1.0 - gbf) * grey[0];
+ cc[3][1] = white[1] * gbf + (1.0 - gbf) * grey[1];
+ cc[3][2] = white[2] * gbf + (1.0 - gbf) * grey[2];
+ cc[3][3] = white[3] * gbf + (1.0 - gbf) * grey[3];
+ if (cmyk)
+ r->add(r, new_rectvs2d(r, (2.0 * bb + r3o2) * hh, bb * hh, 0.125 * hh, hh, cc));
+ else
+ r->add(r, new_rectvs2d(r, (2.0 * bb + r3o2) * hh, bb * hh, 0.25 * hh, hh, cc));
+
+ /* Center CMY wedge */
+ if (cmyk) {
+ cc[0][0] = kblack[0] * gbf + (1.0 - gbf) * grey[0];
+ cc[0][1] = kblack[1] * gbf + (1.0 - gbf) * grey[1];
+ cc[0][2] = kblack[2] * gbf + (1.0 - gbf) * grey[2];
+ cc[0][3] = kblack[3] * gbf + (1.0 - gbf) * grey[3];
+ cc[1][0] = kblack[0] * gbf + (1.0 - gbf) * grey[0];
+ cc[1][1] = kblack[1] * gbf + (1.0 - gbf) * grey[1];
+ cc[1][2] = kblack[2] * gbf + (1.0 - gbf) * grey[2];
+ cc[1][3] = kblack[3] * gbf + (1.0 - gbf) * grey[3];
+ cc[2][0] = white[0] * gbf + (1.0 - gbf) * grey[0];
+ cc[2][1] = white[1] * gbf + (1.0 - gbf) * grey[1];
+ cc[2][2] = white[2] * gbf + (1.0 - gbf) * grey[2];
+ cc[2][3] = white[3] * gbf + (1.0 - gbf) * grey[3];
+ cc[3][0] = white[0] * gbf + (1.0 - gbf) * grey[0];
+ cc[3][1] = white[1] * gbf + (1.0 - gbf) * grey[1];
+ cc[3][2] = white[2] * gbf + (1.0 - gbf) * grey[2];
+ cc[3][3] = white[3] * gbf + (1.0 - gbf) * grey[3];
+ r->add(r, new_rectvs2d(r, (2.0 * bb + r3o2 + 0.125) * hh, bb * hh, 0.125 * hh, hh, cc));
+ }
+
+
+ /* RGB Rectangular chart */
+ } else if (schart == 0) {
+ double bb = 0.07; /* Border proportion */
+ double hh = 50.0; /* Height of hexagon in mm */
+ double sc[6][3] = { /* Saturated color sequence */
+ { 1, 0, 0 },
+ { 1, 0, 1 },
+ { 0, 0, 1 },
+ { 0, 1, 1 },
+ { 0, 1, 0 },
+ { 1, 1, 0 }
+ };
+
+ if (cmyk)
+ error("CMYK not supported for test chart");
+
+ h = (1.0 + 2.0 * bb) * hh;
+ w = (2.0 * bb + 0.20 * 7.0) * hh;
+
+ if ((r = new_render2d(w, h, NULL, res, res, rgb_2d, 0, depth, DITHER)) == NULL) {
+ error("new_render2d() failed");
+ }
+
+ /* Set the default color */
+ c[0] = 0.5;
+ c[1] = 0.5;
+ c[2] = 0.5;
+ r->set_defc(r, c);
+
+ for (i = 0; i < 7; i++) {
+ prim2d *p;
+
+ /* Top rectangle */
+ cc[0][0] = sc[i % 6][0] * gbf + (1.0 - gbf) * 0.5;
+ cc[0][1] = sc[i % 6][1] * gbf + (1.0 - gbf) * 0.5;
+ cc[0][2] = sc[i % 6][2] * gbf + (1.0 - gbf) * 0.5;
+ cc[1][0] = sc[(i+1) % 6][0] * gbf + (1.0 - gbf) * 0.5;
+ cc[1][1] = sc[(i+1) % 6][1] * gbf + (1.0 - gbf) * 0.5;
+ cc[1][2] = sc[(i+1) % 6][2] * gbf + (1.0 - gbf) * 0.5;
+ cc[2][0] = 1.0 * gbf + (1.0 - gbf) * 0.5;
+ cc[2][1] = 1.0 * gbf + (1.0 - gbf) * 0.5;
+ cc[2][2] = 1.0 * gbf + (1.0 - gbf) * 0.5;
+ cc[3][0] = 1.0 * gbf + (1.0 - gbf) * 0.5;
+ cc[3][1] = 1.0 * gbf + (1.0 - gbf) * 0.5;
+ cc[3][2] = 1.0 * gbf + (1.0 - gbf) * 0.5;
+ p = new_rectvs2d(r, (bb + i * 0.2) * hh, (bb + 0.5) * hh, 0.2 * hh, 0.5 * hh, cc);
+ if (smooth) {
+ rectvs2d *pp = (rectvs2d *)p;
+ pp->x_blend = 2;
+ pp->y_blend = 3;
+ }
+ r->add(r, p);
+
+ /* Bottom rectangle */
+ cc[0][0] = 0.0 * gbf + (1.0 - gbf) * 0.5;
+ cc[0][1] = 0.0 * gbf + (1.0 - gbf) * 0.5;
+ cc[0][2] = 0.0 * gbf + (1.0 - gbf) * 0.5;
+ cc[1][0] = 0.0 * gbf + (1.0 - gbf) * 0.5;
+ cc[1][1] = 0.0 * gbf + (1.0 - gbf) * 0.5;
+ cc[1][2] = 0.0 * gbf + (1.0 - gbf) * 0.5;
+ cc[2][0] = sc[i % 6][0] * gbf + (1.0 - gbf) * 0.5;
+ cc[2][1] = sc[i % 6][1] * gbf + (1.0 - gbf) * 0.5;
+ cc[2][2] = sc[i % 6][2] * gbf + (1.0 - gbf) * 0.5;
+ cc[3][0] = sc[(i+1) % 6][0] * gbf + (1.0 - gbf) * 0.5;
+ cc[3][1] = sc[(i+1) % 6][1] * gbf + (1.0 - gbf) * 0.5;
+ cc[3][2] = sc[(i+1) % 6][2] * gbf + (1.0 - gbf) * 0.5;
+ p = new_rectvs2d(r, (bb + i * 0.2) * hh, bb * hh, 0.2 * hh, 0.5 * hh, cc);
+ if (smooth) {
+ rectvs2d *pp = (rectvs2d *)p;
+ pp->x_blend = 2;
+ pp->y_blend = 2;
+ }
+ r->add(r, p);
+ }
+
+ } else { /* Lab step chart */
+ double hh = 50.0; /* Height of hexagon in mm */
+ double bb = 0.05; /* Border proportion */
+ double ss, bs; /* Step size, border size */
+
+ h = hh;
+ w = hh;
+
+ if (cmyk)
+ error("CMYK not supported for test chart");
+
+ bs = (bb * hh)/(schart + 1.0);
+ ss = hh * (1.0 - bb)/schart;
+
+ if ((r = new_render2d(w, h, NULL, res, res, lab_2d, 0, depth, DITHER)) == NULL) {
+ error("new_render2d() failed");
+ }
+
+ /* Set the default color */
+ c[0] = 0.0;
+ c[1] = 0.0;
+ c[2] = 0.0;
+ r->set_defc(r, c);
+
+ for (i = 0; i < schart; i++) {
+ for (j = 0; j < schart; j++) {
+ double lv;
+
+ lv = (double)(j * schart + i)/(schart * schart - 1.0) * 100.0;
+
+ cc[0][0] = lv;
+ cc[0][1] = -127.0;
+ cc[0][2] = -127.0;
+ cc[1][0] = lv;
+ cc[1][1] = 127.0;
+ cc[1][2] = -127.0;
+ cc[2][0] = lv;
+ cc[2][1] = -127.0;
+ cc[2][2] = 127.0;
+ cc[3][0] = lv;
+ cc[3][1] = 127.0;
+ cc[3][2] = 127.0;
+ r->add(r, new_rectvs2d(r, bs + i * (bs + ss),
+ bs + j * (bs + ss),
+ ss, ss, cc));
+ }
+ }
+ }
+
+ r->write(r, outname,1);
+ r->del(r);
+
+ return 0;
+}
+
+