From 00fe329c7e0d898576358da3b919066a197eaff1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jouni=20K=2E=20Sepp=C3=A4nen?= Date: Mon, 27 Jul 2020 13:01:06 +0300 Subject: [PATCH 1/7] Support scale in ttf composite glyphs Fixes #17197 --- extern/ttconv/pprdrv_tt.cpp | 25 +++++++++++++++++++++++++ extern/ttconv/pprdrv_tt2.cpp | 13 ++++++++++++- extern/ttconv/truetype.h | 9 +++++++++ 3 files changed, 46 insertions(+), 1 deletion(-) diff --git a/extern/ttconv/pprdrv_tt.cpp b/extern/ttconv/pprdrv_tt.cpp index 934215470808..47945bbfe02e 100644 --- a/extern/ttconv/pprdrv_tt.cpp +++ b/extern/ttconv/pprdrv_tt.cpp @@ -107,6 +107,31 @@ Fixed getFixed(BYTE *s) return val; } /* end of getFixed() */ +/* +** Get a 16 bit fixed point (2.14) number. +*/ +F2DOT14 getF2DOT14(BYTE *s) +{ + F2DOT14 val={0, 0}; + + int sign = s[0] & 0x80; + int bit = (s[0] & 0x40) >> 6; + if (sign) { + val.whole = bit-2; + } else { + val.whole = bit; + } + val.fraction = ((s[0] & 0x3f) << 8) + s[1]; + + return val; +} + +float F2DOT14value(F2DOT14 f) +{ + return f.whole + (float)f.fraction/16384; +} + + /*----------------------------------------------------------------------- ** Load a TrueType font table into memory and return a pointer to it. ** The font's "file" and "offset_table" fields must be set before this diff --git a/extern/ttconv/pprdrv_tt2.cpp b/extern/ttconv/pprdrv_tt2.cpp index 058bc005348b..691948456247 100644 --- a/extern/ttconv/pprdrv_tt2.cpp +++ b/extern/ttconv/pprdrv_tt2.cpp @@ -417,6 +417,7 @@ void GlyphToType3::do_composite(TTStreamWriter& stream, struct TTFONT *font, BYT USHORT glyphIndex; int arg1; int arg2; + F2DOT14 mat00 = {1, 0}, mat01 = {0, 0}, mat10 = {0, 0}, mat11 = {1, 0}; /* Once around this loop for each component. */ do @@ -444,14 +445,21 @@ void GlyphToType3::do_composite(TTStreamWriter& stream, struct TTFONT *font, BYT if (flags & WE_HAVE_A_SCALE) { + mat00 = mat11 = getF2DOT14(glyph); glyph += 2; } else if (flags & WE_HAVE_AN_X_AND_Y_SCALE) { + mat00 = getF2DOT14(glyph); + mat11 = getF2DOT14(glyph+2); glyph += 4; } else if (flags & WE_HAVE_A_TWO_BY_TWO) { + mat00 = getF2DOT14(glyph); + mat01 = getF2DOT14(glyph+2); + mat10 = getF2DOT14(glyph+4); + mat11 = getF2DOT14(glyph+6); glyph += 8; } else @@ -472,7 +480,10 @@ void GlyphToType3::do_composite(TTStreamWriter& stream, struct TTFONT *font, BYT subglyph here. However, that doesn't seem to work with xpdf or gs (only acrobat), so instead, this just includes the subglyph here inline. */ - stream.printf("q 1 0 0 1 %d %d cm\n", topost(arg1), topost(arg2)); + stream.printf("q %.6f %.6f %.6f %.6f %d %d cm\n", + F2DOT14value(mat00), F2DOT14value(mat01), + F2DOT14value(mat10), F2DOT14value(mat11), + topost(arg1), topost(arg2)); } else { diff --git a/extern/ttconv/truetype.h b/extern/ttconv/truetype.h index 86be14fe3705..c4dadd4d4c3b 100644 --- a/extern/ttconv/truetype.h +++ b/extern/ttconv/truetype.h @@ -41,6 +41,13 @@ typedef struct unsigned short int fraction; } Fixed; +/* A 2.14 fixed point number */ +typedef struct + { + SHORT whole; + USHORT fraction; + } F2DOT14; + /* This structure tells what we have found out about */ /* the current font. */ struct TTFONT @@ -86,6 +93,8 @@ struct TTFONT ULONG getULONG(BYTE *p); USHORT getUSHORT(BYTE *p); Fixed getFixed(BYTE *p); +F2DOT14 getF2DOT14(BYTE *p); +float F2DOT14value(F2DOT14 f); /* ** Get an funits word. From be60f79ea705841c50799bf0ee9ea851490bb2aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jouni=20K=2E=20Sepp=C3=A4nen?= Date: Mon, 27 Jul 2020 16:34:29 +0300 Subject: [PATCH 2/7] Add a test The GNU Free Serif font has a wide variety of characters with which we can exercise the linear transforms used in TTF composite glyphs. --- LICENSE/LICENSE_GNU_FREEFONT | 739 ++++++++++++++++++ lib/matplotlib/tests/FreeSerifSubset.ttf | Bin 0 -> 22904 bytes .../test_ttconv/ttconv_transforms.pdf | Bin 0 -> 19224 bytes lib/matplotlib/tests/test_ttconv.py | 14 + setupext.py | 1 + 5 files changed, 754 insertions(+) create mode 100644 LICENSE/LICENSE_GNU_FREEFONT create mode 100644 lib/matplotlib/tests/FreeSerifSubset.ttf create mode 100644 lib/matplotlib/tests/baseline_images/test_ttconv/ttconv_transforms.pdf diff --git a/LICENSE/LICENSE_GNU_FREEFONT b/LICENSE/LICENSE_GNU_FREEFONT new file mode 100644 index 000000000000..d9f97b25a0f3 --- /dev/null +++ b/LICENSE/LICENSE_GNU_FREEFONT @@ -0,0 +1,739 @@ +The FreeSerifSubset.ttf file is a subset of the Free Serif font from +the GNU FreeFont collection. It is included here as test data only, +but the following license applies. + +Free UCS scalable fonts is free software; you can redistribute it +and/or modify it under the terms of the GNU General Public License as +published by the Free Software Foundation; either version 3 of the +License, or (at your option) any later version. + +The fonts are distributed in the hope that they will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301, USA. + +As a special exception, if you create a document which uses this font, +and embed this font or unaltered portions of this font into the +document, this font does not by itself cause the resulting document to +be covered by the GNU General Public License. This exception does not +however invalidate any other reasons why the document might be covered +by the GNU General Public License. If you modify this font, you may +extend this exception to your version of the font, but you are not +obligated to do so. If you do not wish to do so, delete this exception +statement from your version. + +Clarification of exception, regarding intended use of embedded fonts + +The exception to the GNU General Public License for the GNU FreeFont +software exempts a user that embeds part or all of the GNU FreeFont +software in a document, as well as subsequent users and distributors +of the document, from complying with the GNU GPL under some +circumstances. + +Specifically, this exemption applies when the embedder has not +modified the GNU FreeFont software before embedding it. This is true +even though portions of the software become part of the document. + +Therefore users of fonts released with this exception need not concern +themselves with the license terms to: + +* Create a printable file using the fonts. +* Publish such a file. +* Redistribute such a file. +* Publicly display such a file. +* Print such a file or display it on the screen. + +However anyone distributing the font software as software separately +from the document, even if the way the font software was obtained was +to extract it from a document, would have to comply with the GNU GPL. + +A modified version of the GNU FreeFont software must comply with the +GNU GPL. It may optionally carry the same exception as the GNU +FreeFont software itself, and we recommend releasing modified versions +that way. If it does, then users will likewise be permitted to embed +the modified version in documents and be exempt from the GNU GPL +requirements on those documents. + + + + + + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/lib/matplotlib/tests/FreeSerifSubset.ttf b/lib/matplotlib/tests/FreeSerifSubset.ttf new file mode 100644 index 0000000000000000000000000000000000000000..1b49b90eabbf65d8948b67866dfc854f0a190e01 GIT binary patch literal 22904 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 SO(tJw-~WJK+&BN9;QtLS{+wq3 literal 0 HcmV?d00001 diff --git a/lib/matplotlib/tests/baseline_images/test_ttconv/ttconv_transforms.pdf b/lib/matplotlib/tests/baseline_images/test_ttconv/ttconv_transforms.pdf new file mode 100644 index 0000000000000000000000000000000000000000..dc6fe7a0cc3c35f4d6814785f60aff35b77cf7da GIT binary patch literal 19224 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 Date: Mon, 27 Jul 2020 19:38:54 +0300 Subject: [PATCH 3/7] Stay within the allowed line length --- lib/matplotlib/tests/test_ttconv.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/matplotlib/tests/test_ttconv.py b/lib/matplotlib/tests/test_ttconv.py index ebfd4429c548..f7244cb70592 100644 --- a/lib/matplotlib/tests/test_ttconv.py +++ b/lib/matplotlib/tests/test_ttconv.py @@ -21,7 +21,8 @@ def test_truetype_conversion(recwarn): def test_ttconv_transforms(): matplotlib.rcParams['pdf.fonttype'] = 3 fig, ax = plt.subplots() - kw = {'font': Path(__file__).with_name("FreeSerifSubset.ttf"), 'fontsize': 14} + kw = {'font': Path(__file__).with_name("FreeSerifSubset.ttf"), + 'fontsize': 14} # characters where Free Serif uses various scales and linear transforms # e.g. the right paren is a reflected left paren ax.text(.1, .1, "parens, FAX, u with two diacritics: ()℻ǘ", **kw) From e78d502867e8f211546447d314a5cd5739694d82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jouni=20K=2E=20Sepp=C3=A4nen?= Date: Tue, 28 Jul 2020 10:14:46 +0300 Subject: [PATCH 4/7] Trim trailing zeroes in ttconv output These could increase the file length in case of fonts with many composite glyphs. --- extern/ttconv/pprdrv_tt.cpp | 34 ++++++++++++++++++++++++++++++++-- extern/ttconv/pprdrv_tt2.cpp | 17 ++++++++++++----- extern/ttconv/truetype.h | 2 +- 3 files changed, 45 insertions(+), 8 deletions(-) diff --git a/extern/ttconv/pprdrv_tt.cpp b/extern/ttconv/pprdrv_tt.cpp index 47945bbfe02e..7250e6f7d43f 100644 --- a/extern/ttconv/pprdrv_tt.cpp +++ b/extern/ttconv/pprdrv_tt.cpp @@ -109,6 +109,13 @@ Fixed getFixed(BYTE *s) /* ** Get a 16 bit fixed point (2.14) number. +** +** The value range is from -2.0 to a little under 2.0. The two +** most-significant bits encode the whole part in two's-complement +** format and the remaining 14 bits encode the numerator n of the +** fraction n/16384 to be added to the whole part. +** +** https://docs.microsoft.com/en-us/typography/opentype/otspec181/otff#data-types */ F2DOT14 getF2DOT14(BYTE *s) { @@ -126,9 +133,32 @@ F2DOT14 getF2DOT14(BYTE *s) return val; } -float F2DOT14value(F2DOT14 f) +/* +** Convert a fixed-point 2.14 number to a newly-allocated string. +** Use at most six decimals but remove trailing zeroes and possibly +** the decimal point. +*/ +char* F2DOT14value(F2DOT14 f) { - return f.whole + (float)f.fraction/16384; + const size_t maxlen = strlen("-1.234567") + 1; + char *value = (char*)calloc(sizeof(char), maxlen); + if (value == NULL || + snprintf(value, maxlen, "%.6f", f.whole + (float)f.fraction/16384) < 0) { + abort(); + } + + char *ptr = &value[maxlen-1]; + while (ptr > value && *ptr == '\0') { + ptr--; + } + while (ptr > value && *ptr == '0') { + *ptr-- = '\0'; + } + if (ptr > value && *ptr == '.') { + *ptr = '\0'; + } + + return value; } diff --git a/extern/ttconv/pprdrv_tt2.cpp b/extern/ttconv/pprdrv_tt2.cpp index 691948456247..8b188c7b772c 100644 --- a/extern/ttconv/pprdrv_tt2.cpp +++ b/extern/ttconv/pprdrv_tt2.cpp @@ -409,7 +409,9 @@ void GlyphToType3::load_char(TTFONT* font, BYTE *glyph) } /* end of load_char() */ /* -** Emmit PostScript code for a composite character. +** Emit PostScript code for a composite character. +** +** https://docs.microsoft.com/en-us/typography/opentype/spec/glyf#composite-glyph-description */ void GlyphToType3::do_composite(TTStreamWriter& stream, struct TTFONT *font, BYTE *glyph) { @@ -480,10 +482,15 @@ void GlyphToType3::do_composite(TTStreamWriter& stream, struct TTFONT *font, BYT subglyph here. However, that doesn't seem to work with xpdf or gs (only acrobat), so instead, this just includes the subglyph here inline. */ - stream.printf("q %.6f %.6f %.6f %.6f %d %d cm\n", - F2DOT14value(mat00), F2DOT14value(mat01), - F2DOT14value(mat10), F2DOT14value(mat11), - topost(arg1), topost(arg2)); + char *s00 = F2DOT14value(mat00), *s01 = F2DOT14value(mat01), + *s10 = F2DOT14value(mat10), *s11 = F2DOT14value(mat11); + + stream.printf("q %s %s %s %s %d %d cm\n", + s00, s01, s10, s11, topost(arg1), topost(arg2)); + free(s00); + free(s01); + free(s10); + free(s11); } else { diff --git a/extern/ttconv/truetype.h b/extern/ttconv/truetype.h index c4dadd4d4c3b..95536398a74d 100644 --- a/extern/ttconv/truetype.h +++ b/extern/ttconv/truetype.h @@ -94,7 +94,7 @@ ULONG getULONG(BYTE *p); USHORT getUSHORT(BYTE *p); Fixed getFixed(BYTE *p); F2DOT14 getF2DOT14(BYTE *p); -float F2DOT14value(F2DOT14 f); +char *F2DOT14value(F2DOT14 f); /* ** Get an funits word. From d0779be222a598028e86704a2c1339c46f6ee946 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jouni=20K=2E=20Sepp=C3=A4nen?= Date: Sat, 1 Aug 2020 08:43:35 +0300 Subject: [PATCH 5/7] Make F2DOT14 a typedef of Fixed --- extern/ttconv/truetype.h | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/extern/ttconv/truetype.h b/extern/ttconv/truetype.h index 95536398a74d..b0e0f2e14564 100644 --- a/extern/ttconv/truetype.h +++ b/extern/ttconv/truetype.h @@ -42,11 +42,7 @@ typedef struct } Fixed; /* A 2.14 fixed point number */ -typedef struct - { - SHORT whole; - USHORT fraction; - } F2DOT14; +typedef Fixed F2DOT14; /* This structure tells what we have found out about */ /* the current font. */ From f7799e397ccf115c135ff9ff2ae28b7d65a0b516 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jouni=20K=2E=20Sepp=C3=A4nen?= Date: Wed, 5 Aug 2020 09:44:27 +0300 Subject: [PATCH 6/7] Simplify test decorator Co-authored-by: Elliott Sales de Andrade --- lib/matplotlib/tests/test_ttconv.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/matplotlib/tests/test_ttconv.py b/lib/matplotlib/tests/test_ttconv.py index f7244cb70592..d31352ef4743 100644 --- a/lib/matplotlib/tests/test_ttconv.py +++ b/lib/matplotlib/tests/test_ttconv.py @@ -17,7 +17,7 @@ def test_truetype_conversion(recwarn): ax.set_yticks([]) -@image_comparison(["ttconv_transforms"], extensions=["pdf"]) +@image_comparison(["ttconv_transforms.pdf"]) def test_ttconv_transforms(): matplotlib.rcParams['pdf.fonttype'] = 3 fig, ax = plt.subplots() From 527c96979b03aee096933f56a0598df084813d87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jouni=20K=2E=20Sepp=C3=A4nen?= Date: Wed, 5 Aug 2020 09:44:59 +0300 Subject: [PATCH 7/7] Use sizeof instead of strlen+1 Co-authored-by: Elliott Sales de Andrade --- extern/ttconv/pprdrv_tt.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extern/ttconv/pprdrv_tt.cpp b/extern/ttconv/pprdrv_tt.cpp index 7250e6f7d43f..18d8affe3ec2 100644 --- a/extern/ttconv/pprdrv_tt.cpp +++ b/extern/ttconv/pprdrv_tt.cpp @@ -140,7 +140,7 @@ F2DOT14 getF2DOT14(BYTE *s) */ char* F2DOT14value(F2DOT14 f) { - const size_t maxlen = strlen("-1.234567") + 1; + const size_t maxlen = sizeof("-1.234567"); char *value = (char*)calloc(sizeof(char), maxlen); if (value == NULL || snprintf(value, maxlen, "%.6f", f.whole + (float)f.fraction/16384) < 0) {