From 658fc65e084e11fef393ede9e4f9151f8ace077f Mon Sep 17 00:00:00 2001 From: Elliott Sales de Andrade Date: Thu, 12 Jun 2025 05:23:10 -0400 Subject: [PATCH 1/3] Handle some simpler colour fonts This adds support for fonts with colour glyphs supported by FreeType. Specifically, this should mean COLRv0 fonts. There also exist some other colour font types, which are not supported: * CBDT is a non-scalable bitmap format and we don't support those, but it may be possible if we do a scaling ourselves. https://github.com/matplotlib/matplotlib/issues/31207 * COLRv1 essentially requires a full renderer setup. https://github.com/matplotlib/matplotlib/issues/31210 * SBIX is another non-scalable bitmap format likee CBDT. https://github.com/matplotlib/matplotlib/issues/31208 * SVG requires a parser (though it's some font-specific subset of the whole SVG spec). https://github.com/matplotlib/matplotlib/issues/31211 Fixes #31209 --- lib/matplotlib/backends/backend_agg.py | 30 ++++++++----- src/_backend_agg.h | 35 ++++++++++++--- src/_backend_agg_wrapper.cpp | 62 ++++++++++++++++++++++++++ src/ft2font_wrapper.cpp | 26 +++++++++-- 4 files changed, 132 insertions(+), 21 deletions(-) diff --git a/lib/matplotlib/backends/backend_agg.py b/lib/matplotlib/backends/backend_agg.py index f0006a2d7dbe..cc9e03f44c87 100644 --- a/lib/matplotlib/backends/backend_agg.py +++ b/lib/matplotlib/backends/backend_agg.py @@ -56,6 +56,10 @@ def get_hinting_flag(): return mapping[mpl.rcParams['text.hinting']] +def _get_load_flags(): + return get_hinting_flag() | LoadFlags.COLOR | LoadFlags.NO_SVG + + class RendererAgg(RendererBase): """ The renderer handles all the drawing primitives using a graphics @@ -176,7 +180,7 @@ def _draw_text_glyphs_and_boxes(self, gc, x, y, angle, glyphs, boxes): # y is downwards. cos = math.cos(math.radians(angle)) sin = math.sin(math.radians(angle)) - load_flags = get_hinting_flag() + load_flags = _get_load_flags() for font, size, glyph_index, slant, extend, dx, dy in glyphs: # dy is upwards. font.set_size(size, self.dpi) hf = font._hinting_factor @@ -192,13 +196,19 @@ def _draw_text_glyphs_and_boxes(self, gc, x, y, angle, glyphs, boxes): glyph_index, load_flags, RenderMode.NORMAL if gc.get_antialiased() else RenderMode.MONO) buffer = bitmap.buffer - if not gc.get_antialiased(): - buffer *= 0xff - # draw_text_image's y is downwards & the bitmap bottom side. - self._renderer.draw_text_image( - buffer, - bitmap.left, int(self.height) - bitmap.top + buffer.shape[0], - 0, gc) + if buffer.ndim == 3: + self._renderer.draw_text_bgra_image( + gc, + bitmap.left, bitmap.top - buffer.shape[0], + buffer) + else: + if not gc.get_antialiased(): + buffer *= 0xff + # draw_text_image's y is downwards & the bitmap bottom side. + self._renderer.draw_text_image( + buffer, + bitmap.left, int(self.height) - bitmap.top + buffer.shape[0], + 0, gc) rgba = gc.get_rgb() if len(rgba) == 3 or gc.get_forced_alpha(): @@ -240,7 +250,7 @@ def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None): return self.draw_mathtext(gc, x, y, s, prop, angle) font = self._prepare_font(prop) items = font._layout( - s, flags=get_hinting_flag(), + s, flags=_get_load_flags(), features=mtext.get_fontfeatures() if mtext is not None else None, language=mtext.get_language() if mtext is not None else None) size = prop.get_size_in_points() @@ -262,7 +272,7 @@ def get_text_width_height_descent(self, s, prop, ismath): return parse.width, parse.height, parse.depth font = self._prepare_font(prop) - font.set_text(s, 0.0, flags=get_hinting_flag()) + font.set_text(s, 0.0, flags=_get_load_flags()) w, h = font.get_width_height() # width and height of unrotated string d = font.get_descent() w /= 64.0 # convert from subpixels diff --git a/src/_backend_agg.h b/src/_backend_agg.h index a4e2aa10040d..4e4850f81ad9 100644 --- a/src/_backend_agg.h +++ b/src/_backend_agg.h @@ -12,6 +12,7 @@ #include #include #include +#include #include #include "agg_alpha_mask_u8.h" @@ -152,11 +153,18 @@ class RendererAgg template void draw_text_image(GCAgg &gc, ImageArray &image, int x, int y, double angle); - template + template void draw_image(GCAgg &gc, double x, double y, - ImageArray &image); + ImageArray &image, + bool flip_image = false); template +template inline void RendererAgg::draw_image(GCAgg &gc, double x, double y, - ImageArray &image) + ImageArray &image, + bool flip_image) { double alpha = gc.alpha; @@ -787,8 +796,9 @@ inline void RendererAgg::draw_image(GCAgg &gc, agg::rendering_buffer buffer; buffer.attach(image.mutable_data(0, 0, 0), (unsigned)image.shape(1), (unsigned)image.shape(0), - -(int)image.shape(1) * 4); - pixfmt pixf(buffer); + (flip_image ? 4 : -4) * image.shape(1)); + // NOTE: this pixel format only describes the pixel order, not the colour state. + ImagePixelFormat pixf(buffer); if (has_clippath) { agg::trans_affine mtx; @@ -823,10 +833,21 @@ inline void RendererAgg::draw_image(GCAgg &gc, theRasterizer.add_path(rect2); agg::render_scanlines(theRasterizer, scanlineAlphaMask, ri); + } else if constexpr(!std::is_same_v) { + static_assert(std::is_same_v, + "Blender order must be RGBA"); + auto imgFmt = Blender{renderingBuffer}; + auto rendererImage = agg::renderer_base{imgFmt}; + rendererImage.reset_clipping(true); + set_clipbox(gc.cliprect, rendererImage); + rendererImage.blend_from( + pixf, nullptr, (int)x, (int)(height - (y + image.shape(0))), + (agg::int8u)(alpha * 255)); } else { set_clipbox(gc.cliprect, rendererBase); rendererBase.blend_from( - pixf, nullptr, (int)x, (int)(height - (y + image.shape(0))), (agg::int8u)(alpha * 255)); + pixf, nullptr, (int)x, (int)(height - (y + image.shape(0))), + (agg::int8u)(alpha * 255)); } rendererBase.reset_clipping(true); diff --git a/src/_backend_agg_wrapper.cpp b/src/_backend_agg_wrapper.cpp index 11d45773d186..61b0c6f42e13 100644 --- a/src/_backend_agg_wrapper.cpp +++ b/src/_backend_agg_wrapper.cpp @@ -131,6 +131,66 @@ PyRendererAgg_draw_image(RendererAgg *self, self->draw_image(gc, x, y, image); } +//========================================================blender_rgba_pre_plain +// Blends premultiplied colors into a plain (non-premultiplied) buffer. +template +struct blender_rgba_pre_plain : agg::conv_rgba_pre +{ + typedef ColorT color_type; + typedef Order order_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + typedef typename color_type::long_type long_type; + + // First premultiply the destination buffer, blend pixels using the premultiplied + // form of Alvy-Ray Smith's compositing function, then demultiply the destination. + + //-------------------------------------------------------------------- + static AGG_INLINE void blend_pix(value_type* p, + value_type cr, value_type cg, value_type cb, + value_type alpha, agg::cover_type cover) + { + blend_pix(p, + color_type::mult_cover(cr, cover), + color_type::mult_cover(cg, cover), + color_type::mult_cover(cb, cover), + color_type::mult_cover(alpha, cover)); + } + + //-------------------------------------------------------------------- + static AGG_INLINE void blend_pix(value_type* p, + value_type cr, value_type cg, value_type cb, + value_type alpha) + { + agg::multiplier_rgba::premultiply(p); + p[Order::R] = color_type::prelerp(p[Order::R], cr, alpha); + p[Order::G] = color_type::prelerp(p[Order::G], cg, alpha); + p[Order::B] = color_type::prelerp(p[Order::B], cb, alpha); + p[Order::A] = color_type::prelerp(p[Order::A], alpha, alpha); + agg::multiplier_rgba::demultiply(p); + } +}; + +static void +PyRendererAgg_draw_text_bgra_image(RendererAgg *self, + GCAgg &gc, + int x, + int y, + py::array_t image_obj) +{ + // TODO: This really shouldn't be mutable, but Agg's renderer buffers aren't const. + auto image = image_obj.mutable_unchecked<3>(); + + gc.alpha = 1.0; + + // FreeType uses premultiplied BGRA, so use a different pixel format than draw_image. + using blender_rgba32_pre_plain = blender_rgba_pre_plain; + using pixfmt_rgba32_pre_plain = agg::pixfmt_alpha_blend_rgba; + self->draw_image( + gc, x, y, image, true); +} + static void PyRendererAgg_draw_path_collection(RendererAgg *self, GCAgg &gc, @@ -227,6 +287,8 @@ PYBIND11_MODULE(_backend_agg, m, py::mod_gil_not_used()) "face"_a = nullptr) .def("draw_text_image", &PyRendererAgg_draw_text_image, "image"_a, "x"_a, "y"_a, "angle"_a, "gc"_a) + .def("draw_text_bgra_image", &PyRendererAgg_draw_text_bgra_image, + "gc"_a, "x"_a, "y"_a, "image"_a.noconvert(true)) .def("draw_image", &PyRendererAgg_draw_image, "gc"_a, "x"_a, "y"_a, "image"_a) .def("draw_path_collection", &PyRendererAgg_draw_path_collection, diff --git a/src/ft2font_wrapper.cpp b/src/ft2font_wrapper.cpp index bf345cd1d044..4dcba406af66 100644 --- a/src/ft2font_wrapper.cpp +++ b/src/ft2font_wrapper.cpp @@ -297,14 +297,22 @@ struct PyPositionedBitmap { left{slot->bitmap_left}, top{slot->bitmap_top}, owning{true} { FT_Bitmap_Init(&bitmap); - FT_CHECK(FT_Bitmap_Convert, _ft2Library, &slot->bitmap, &bitmap, 1); + if (slot->bitmap.pixel_mode == FT_PIXEL_MODE_MONO) { + FT_CHECK(FT_Bitmap_Convert, _ft2Library, &slot->bitmap, &bitmap, 1); + } else { + FT_CHECK(FT_Bitmap_Copy, _ft2Library, &slot->bitmap, &bitmap); + } } PyPositionedBitmap(FT_BitmapGlyph bg) : left{bg->left}, top{bg->top}, owning{true} { FT_Bitmap_Init(&bitmap); - FT_CHECK(FT_Bitmap_Convert, _ft2Library, &bg->bitmap, &bitmap, 1); + if (bg->bitmap.pixel_mode == FT_PIXEL_MODE_MONO) { + FT_CHECK(FT_Bitmap_Convert, _ft2Library, &bg->bitmap, &bitmap, 1); + } else { + FT_CHECK(FT_Bitmap_Copy, _ft2Library, &bg->bitmap, &bitmap); + } } PyPositionedBitmap(PyPositionedBitmap& other) = delete; // Non-copyable. @@ -1693,9 +1701,19 @@ PYBIND11_MODULE(ft2font, m, py::mod_gil_not_used()) .def_readonly("top", &PyPositionedBitmap::top) .def_property_readonly( "buffer", [](PyPositionedBitmap &self) -> py::array { - return {{self.bitmap.rows, self.bitmap.width}, + if (self.bitmap.pixel_mode == FT_PIXEL_MODE_BGRA) { + return { + {self.bitmap.rows, self.bitmap.width, 4u}, + {self.bitmap.pitch, 4, 1}, + self.bitmap.buffer + }; + } else { + return { + {self.bitmap.rows, self.bitmap.width}, {self.bitmap.pitch, 1}, - self.bitmap.buffer}; + self.bitmap.buffer + }; + } }) ; From 728ea52a8b476dad4f5cf97cbe0c3a4346384c79 Mon Sep 17 00:00:00 2001 From: Elliott Sales de Andrade Date: Thu, 5 Feb 2026 02:45:16 -0500 Subject: [PATCH 2/3] TST: Add a test for COLRv0 fonts --- LICENSE/LICENSE_OPENMOJI | 427 ++++++++++++++++++ doc/project/license.rst | 6 + lib/matplotlib/testing/__init__.py | 90 ++++ lib/matplotlib/testing/__init__.pyi | 4 + lib/matplotlib/testing/conftest.py | 2 + .../baseline_images/test_text/colour.png | Bin 0 -> 82464 bytes .../OpenMoji-color-glyf_colr_0-subset.ttf | Bin 0 -> 24144 bytes lib/matplotlib/tests/test_text.py | 35 ++ 8 files changed, 564 insertions(+) create mode 100644 LICENSE/LICENSE_OPENMOJI create mode 100644 lib/matplotlib/tests/baseline_images/test_text/colour.png create mode 100644 lib/matplotlib/tests/data/OpenMoji-color-glyf_colr_0-subset.ttf diff --git a/LICENSE/LICENSE_OPENMOJI b/LICENSE/LICENSE_OPENMOJI new file mode 100644 index 000000000000..cc3e2459dc5c --- /dev/null +++ b/LICENSE/LICENSE_OPENMOJI @@ -0,0 +1,427 @@ +Attribution-ShareAlike 4.0 International + +======================================================================= + +Creative Commons Corporation ("Creative Commons") is not a law firm and +does not provide legal services or legal advice. Distribution of +Creative Commons public licenses does not create a lawyer-client or +other relationship. Creative Commons makes its licenses and related +information available on an "as-is" basis. Creative Commons gives no +warranties regarding its licenses, any material licensed under their +terms and conditions, or any related information. Creative Commons +disclaims all liability for damages resulting from their use to the +fullest extent possible. + +Using Creative Commons Public Licenses + +Creative Commons public licenses provide a standard set of terms and +conditions that creators and other rights holders may use to share +original works of authorship and other material subject to copyright +and certain other rights specified in the public license below. The +following considerations are for informational purposes only, are not +exhaustive, and do not form part of our licenses. + + Considerations for licensors: Our public licenses are + intended for use by those authorized to give the public + permission to use material in ways otherwise restricted by + copyright and certain other rights. Our licenses are + irrevocable. Licensors should read and understand the terms + and conditions of the license they choose before applying it. + Licensors should also secure all rights necessary before + applying our licenses so that the public can reuse the + material as expected. Licensors should clearly mark any + material not subject to the license. This includes other CC- + licensed material, or material used under an exception or + limitation to copyright. More considerations for licensors: + wiki.creativecommons.org/Considerations_for_licensors + + Considerations for the public: By using one of our public + licenses, a licensor grants the public permission to use the + licensed material under specified terms and conditions. If + the licensor's permission is not necessary for any reason--for + example, because of any applicable exception or limitation to + copyright--then that use is not regulated by the license. Our + licenses grant only permissions under copyright and certain + other rights that a licensor has authority to grant. Use of + the licensed material may still be restricted for other + reasons, including because others have copyright or other + rights in the material. A licensor may make special requests, + such as asking that all changes be marked or described. + Although not required by our licenses, you are encouraged to + respect those requests where reasonable. More considerations + for the public: + wiki.creativecommons.org/Considerations_for_licensees + +======================================================================= + +Creative Commons Attribution-ShareAlike 4.0 International Public +License + +By exercising the Licensed Rights (defined below), You accept and agree +to be bound by the terms and conditions of this Creative Commons +Attribution-ShareAlike 4.0 International Public License ("Public +License"). To the extent this Public License may be interpreted as a +contract, You are granted the Licensed Rights in consideration of Your +acceptance of these terms and conditions, and the Licensor grants You +such rights in consideration of benefits the Licensor receives from +making the Licensed Material available under these terms and +conditions. + + +Section 1 -- Definitions. + + a. Adapted Material means material subject to Copyright and Similar + Rights that is derived from or based upon the Licensed Material + and in which the Licensed Material is translated, altered, + arranged, transformed, or otherwise modified in a manner requiring + permission under the Copyright and Similar Rights held by the + Licensor. For purposes of this Public License, where the Licensed + Material is a musical work, performance, or sound recording, + Adapted Material is always produced where the Licensed Material is + synched in timed relation with a moving image. + + b. Adapter's License means the license You apply to Your Copyright + and Similar Rights in Your contributions to Adapted Material in + accordance with the terms and conditions of this Public License. + + c. BY-SA Compatible License means a license listed at + creativecommons.org/compatiblelicenses, approved by Creative + Commons as essentially the equivalent of this Public License. + + d. Copyright and Similar Rights means copyright and/or similar rights + closely related to copyright including, without limitation, + performance, broadcast, sound recording, and Sui Generis Database + Rights, without regard to how the rights are labeled or + categorized. For purposes of this Public License, the rights + specified in Section 2(b)(1)-(2) are not Copyright and Similar + Rights. + + e. Effective Technological Measures means those measures that, in the + absence of proper authority, may not be circumvented under laws + fulfilling obligations under Article 11 of the WIPO Copyright + Treaty adopted on December 20, 1996, and/or similar international + agreements. + + f. Exceptions and Limitations means fair use, fair dealing, and/or + any other exception or limitation to Copyright and Similar Rights + that applies to Your use of the Licensed Material. + + g. License Elements means the license attributes listed in the name + of a Creative Commons Public License. The License Elements of this + Public License are Attribution and ShareAlike. + + h. Licensed Material means the artistic or literary work, database, + or other material to which the Licensor applied this Public + License. + + i. Licensed Rights means the rights granted to You subject to the + terms and conditions of this Public License, which are limited to + all Copyright and Similar Rights that apply to Your use of the + Licensed Material and that the Licensor has authority to license. + + j. Licensor means the individual(s) or entity(ies) granting rights + under this Public License. + + k. Share means to provide material to the public by any means or + process that requires permission under the Licensed Rights, such + as reproduction, public display, public performance, distribution, + dissemination, communication, or importation, and to make material + available to the public including in ways that members of the + public may access the material from a place and at a time + individually chosen by them. + + l. Sui Generis Database Rights means rights other than copyright + resulting from Directive 96/9/EC of the European Parliament and of + the Council of 11 March 1996 on the legal protection of databases, + as amended and/or succeeded, as well as other essentially + equivalent rights anywhere in the world. + + m. You means the individual or entity exercising the Licensed Rights + under this Public License. Your has a corresponding meaning. + + +Section 2 -- Scope. + + a. License grant. + + 1. Subject to the terms and conditions of this Public License, + the Licensor hereby grants You a worldwide, royalty-free, + non-sublicensable, non-exclusive, irrevocable license to + exercise the Licensed Rights in the Licensed Material to: + + a. reproduce and Share the Licensed Material, in whole or + in part; and + + b. produce, reproduce, and Share Adapted Material. + + 2. Exceptions and Limitations. For the avoidance of doubt, where + Exceptions and Limitations apply to Your use, this Public + License does not apply, and You do not need to comply with + its terms and conditions. + + 3. Term. The term of this Public License is specified in Section + 6(a). + + 4. Media and formats; technical modifications allowed. The + Licensor authorizes You to exercise the Licensed Rights in + all media and formats whether now known or hereafter created, + and to make technical modifications necessary to do so. The + Licensor waives and/or agrees not to assert any right or + authority to forbid You from making technical modifications + necessary to exercise the Licensed Rights, including + technical modifications necessary to circumvent Effective + Technological Measures. For purposes of this Public License, + simply making modifications authorized by this Section 2(a) + (4) never produces Adapted Material. + + 5. Downstream recipients. + + a. Offer from the Licensor -- Licensed Material. Every + recipient of the Licensed Material automatically + receives an offer from the Licensor to exercise the + Licensed Rights under the terms and conditions of this + Public License. + + b. Additional offer from the Licensor -- Adapted Material. + Every recipient of Adapted Material from You + automatically receives an offer from the Licensor to + exercise the Licensed Rights in the Adapted Material + under the conditions of the Adapter's License You apply. + + c. No downstream restrictions. You may not offer or impose + any additional or different terms or conditions on, or + apply any Effective Technological Measures to, the + Licensed Material if doing so restricts exercise of the + Licensed Rights by any recipient of the Licensed + Material. + + 6. No endorsement. Nothing in this Public License constitutes or + may be construed as permission to assert or imply that You + are, or that Your use of the Licensed Material is, connected + with, or sponsored, endorsed, or granted official status by, + the Licensor or others designated to receive attribution as + provided in Section 3(a)(1)(A)(i). + + b. Other rights. + + 1. Moral rights, such as the right of integrity, are not + licensed under this Public License, nor are publicity, + privacy, and/or other similar personality rights; however, to + the extent possible, the Licensor waives and/or agrees not to + assert any such rights held by the Licensor to the limited + extent necessary to allow You to exercise the Licensed + Rights, but not otherwise. + + 2. Patent and trademark rights are not licensed under this + Public License. + + 3. To the extent possible, the Licensor waives any right to + collect royalties from You for the exercise of the Licensed + Rights, whether directly or through a collecting society + under any voluntary or waivable statutory or compulsory + licensing scheme. In all other cases the Licensor expressly + reserves any right to collect such royalties. + + +Section 3 -- License Conditions. + +Your exercise of the Licensed Rights is expressly made subject to the +following conditions. + + a. Attribution. + + 1. If You Share the Licensed Material (including in modified + form), You must: + + a. retain the following if it is supplied by the Licensor + with the Licensed Material: + + i. identification of the creator(s) of the Licensed + Material and any others designated to receive + attribution, in any reasonable manner requested by + the Licensor (including by pseudonym if + designated); + + ii. a copyright notice; + + iii. a notice that refers to this Public License; + + iv. a notice that refers to the disclaimer of + warranties; + + v. a URI or hyperlink to the Licensed Material to the + extent reasonably practicable; + + b. indicate if You modified the Licensed Material and + retain an indication of any previous modifications; and + + c. indicate the Licensed Material is licensed under this + Public License, and include the text of, or the URI or + hyperlink to, this Public License. + + 2. You may satisfy the conditions in Section 3(a)(1) in any + reasonable manner based on the medium, means, and context in + which You Share the Licensed Material. For example, it may be + reasonable to satisfy the conditions by providing a URI or + hyperlink to a resource that includes the required + information. + + 3. If requested by the Licensor, You must remove any of the + information required by Section 3(a)(1)(A) to the extent + reasonably practicable. + + b. ShareAlike. + + In addition to the conditions in Section 3(a), if You Share + Adapted Material You produce, the following conditions also apply. + + 1. The Adapter's License You apply must be a Creative Commons + license with the same License Elements, this version or + later, or a BY-SA Compatible License. + + 2. You must include the text of, or the URI or hyperlink to, the + Adapter's License You apply. You may satisfy this condition + in any reasonable manner based on the medium, means, and + context in which You Share Adapted Material. + + 3. You may not offer or impose any additional or different terms + or conditions on, or apply any Effective Technological + Measures to, Adapted Material that restrict exercise of the + rights granted under the Adapter's License You apply. + + +Section 4 -- Sui Generis Database Rights. + +Where the Licensed Rights include Sui Generis Database Rights that +apply to Your use of the Licensed Material: + + a. for the avoidance of doubt, Section 2(a)(1) grants You the right + to extract, reuse, reproduce, and Share all or a substantial + portion of the contents of the database; + + b. if You include all or a substantial portion of the database + contents in a database in which You have Sui Generis Database + Rights, then the database in which You have Sui Generis Database + Rights (but not its individual contents) is Adapted Material, + + including for purposes of Section 3(b); and + c. You must comply with the conditions in Section 3(a) if You Share + all or a substantial portion of the contents of the database. + +For the avoidance of doubt, this Section 4 supplements and does not +replace Your obligations under this Public License where the Licensed +Rights include other Copyright and Similar Rights. + + +Section 5 -- Disclaimer of Warranties and Limitation of Liability. + + a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE + EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS + AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF + ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS, + IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION, + WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR + PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS, + ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT + KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT + ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU. + + b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE + TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION, + NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT, + INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES, + COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR + USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN + ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR + DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR + IN PART, THIS LIMITATION MAY NOT APPLY TO YOU. + + c. The disclaimer of warranties and limitation of liability provided + above shall be interpreted in a manner that, to the extent + possible, most closely approximates an absolute disclaimer and + waiver of all liability. + + +Section 6 -- Term and Termination. + + a. This Public License applies for the term of the Copyright and + Similar Rights licensed here. However, if You fail to comply with + this Public License, then Your rights under this Public License + terminate automatically. + + b. Where Your right to use the Licensed Material has terminated under + Section 6(a), it reinstates: + + 1. automatically as of the date the violation is cured, provided + it is cured within 30 days of Your discovery of the + violation; or + + 2. upon express reinstatement by the Licensor. + + For the avoidance of doubt, this Section 6(b) does not affect any + right the Licensor may have to seek remedies for Your violations + of this Public License. + + c. For the avoidance of doubt, the Licensor may also offer the + Licensed Material under separate terms or conditions or stop + distributing the Licensed Material at any time; however, doing so + will not terminate this Public License. + + d. Sections 1, 5, 6, 7, and 8 survive termination of this Public + License. + + +Section 7 -- Other Terms and Conditions. + + a. The Licensor shall not be bound by any additional or different + terms or conditions communicated by You unless expressly agreed. + + b. Any arrangements, understandings, or agreements regarding the + Licensed Material not stated herein are separate from and + independent of the terms and conditions of this Public License. + + +Section 8 -- Interpretation. + + a. For the avoidance of doubt, this Public License does not, and + shall not be interpreted to, reduce, limit, restrict, or impose + conditions on any use of the Licensed Material that could lawfully + be made without permission under this Public License. + + b. To the extent possible, if any provision of this Public License is + deemed unenforceable, it shall be automatically reformed to the + minimum extent necessary to make it enforceable. If the provision + cannot be reformed, it shall be severed from this Public License + without affecting the enforceability of the remaining terms and + conditions. + + c. No term or condition of this Public License will be waived and no + failure to comply consented to unless expressly agreed to by the + Licensor. + + d. Nothing in this Public License constitutes or may be interpreted + as a limitation upon, or waiver of, any privileges and immunities + that apply to the Licensor or You, including from the legal + processes of any jurisdiction or authority. + + +======================================================================= + +Creative Commons is not a party to its public +licenses. Notwithstanding, Creative Commons may elect to apply one of +its public licenses to material it publishes and in those instances +will be considered the “Licensor.” The text of the Creative Commons +public licenses is dedicated to the public domain under the CC0 Public +Domain Dedication. Except for the limited purpose of indicating that +material is shared under a Creative Commons public license or as +otherwise permitted by the Creative Commons policies published at +creativecommons.org/policies, Creative Commons does not authorize the +use of the trademark "Creative Commons" or any other trademark or logo +of Creative Commons without its prior written consent including, +without limitation, in connection with any unauthorized modifications +to any of its public licenses or any other arrangements, +understandings, or agreements concerning use of licensed material. For +the avoidance of doubt, this paragraph does not form part of the +public licenses. + +Creative Commons may be contacted at creativecommons.org. diff --git a/doc/project/license.rst b/doc/project/license.rst index 6a34eff4637d..5242062d36d5 100644 --- a/doc/project/license.rst +++ b/doc/project/license.rst @@ -169,6 +169,12 @@ Fonts .. literalinclude:: ../../LICENSE/LICENSE_LAST_RESORT_FONT :language: none +.. dropdown:: OpenMoji Color (subset) + :class-container: sdd + + .. literalinclude:: ../../LICENSE/LICENSE_OPENMOJI + :language: none + .. dropdown:: STIX :class-container: sdd diff --git a/lib/matplotlib/testing/__init__.py b/lib/matplotlib/testing/__init__.py index 9fcdb6aeee03..0a2fc95e7751 100644 --- a/lib/matplotlib/testing/__init__.py +++ b/lib/matplotlib/testing/__init__.py @@ -320,3 +320,93 @@ def _gen_multi_font_text(): # The resulting string contains 491 unique characters. Some file formats use 8-bit # tables, which the large number of characters exercises twice over. return fonts, test_str + + +def _add_family_suffix(font, suffix): + """ + Add a suffix to all names in a font. + + This code comes from a fontTools snippet: + https://github.com/fonttools/fonttools/blob/main/Snippets/rename-fonts.py + """ + WINDOWS_ENGLISH_IDS = 3, 1, 0x409 + MAC_ROMAN_IDS = 1, 0, 0 + + FAMILY_RELATED_IDS = dict(LEGACY_FAMILY=1, TRUETYPE_UNIQUE_ID=3, FULL_NAME=4, + POSTSCRIPT_NAME=6, PREFERRED_FAMILY=16, WWS_FAMILY=21) + + def get_current_family_name(table): + family_name_rec = None + for plat_id, enc_id, lang_id in (WINDOWS_ENGLISH_IDS, MAC_ROMAN_IDS): + for name_id in (FAMILY_RELATED_IDS['PREFERRED_FAMILY'], + FAMILY_RELATED_IDS['LEGACY_FAMILY']): + family_name_rec = table.getName(nameID=name_id, platformID=plat_id, + platEncID=enc_id, langID=lang_id) + if family_name_rec is not None: + return family_name_rec.toUnicode() + raise ValueError("family name not found; can't add suffix") + + def insert_suffix(string, family_name, suffix): + # check whether family_name is a substring + start = string.find(family_name) + if start != -1: + # insert suffix after the family_name substring + end = start + len(family_name) + return string[:end] + suffix + string[end:] + else: + # it's not, we just append the suffix at the end + return string + suffix + + def rename_record(name_record, family_name, suffix): + string = name_record.toUnicode() + new_string = insert_suffix(string, family_name, suffix) + name_record.string = new_string + return string, new_string + + table = font['name'] + family_name = get_current_family_name(table) + ps_family_name = family_name.replace(' ', '') + ps_suffix = suffix.replace(' ', '') + for rec in table.names: + name_id = rec.nameID + if name_id not in FAMILY_RELATED_IDS.values(): + continue + if name_id == FAMILY_RELATED_IDS['POSTSCRIPT_NAME']: + old, new = rename_record(rec, ps_family_name, ps_suffix) + elif name_id == FAMILY_RELATED_IDS['TRUETYPE_UNIQUE_ID']: + # The Truetype Unique ID rec may contain either the PostScript + # Name or the Full Name string, so we try both + if ps_family_name in rec.toUnicode(): + old, new = rename_record(rec, ps_family_name, ps_suffix) + else: + old, new = rename_record(rec, family_name, suffix) + else: + old, new = rename_record(rec, family_name, suffix) + + return family_name + + +def _generate_font_subset(path, text): + """ + Generate a subset of a font for testing purposes. + + The font name will be suffixed with ' MplSubset'. + + Parameters + ---------- + path : str or bytes or os.PathLike + The path to the font to be subset. The new file will be saved in the same + location with a ``-subset`` suffix. + text : str + The text from which characters to be subset will be derived. Usually fonts do + not have a newline character, so any appearing in this text will be stripped + before subsetting. + """ + from fontTools import subset + options = subset.Options() + font = subset.load_font(path, options) + subsetter = subset.Subsetter(options=options) + subsetter.populate(text=text.replace('\n', '')) + subsetter.subset(font) + _add_family_suffix(font, ' MplSubset') + subset.save_font(font, path.with_stem(path.stem + '-subset'), options) diff --git a/lib/matplotlib/testing/__init__.pyi b/lib/matplotlib/testing/__init__.pyi index accf973615fa..2d409de9ee0d 100644 --- a/lib/matplotlib/testing/__init__.pyi +++ b/lib/matplotlib/testing/__init__.pyi @@ -1,6 +1,8 @@ from collections.abc import Callable +import os import subprocess from typing import Any, IO, Literal, overload +from fontTools.ttLib import TTFont def set_font_settings_for_testing() -> None: ... def set_reproducibility_for_testing() -> None: ... @@ -56,3 +58,5 @@ def ipython_in_subprocess( ) -> None: ... def is_ci_environment() -> bool: ... def _gen_multi_font_text() -> tuple[list[str], str]: ... +def _add_family_suffix(font: TTFont, suffix: str) -> None: ... +def _generate_font_subset(path: str | bytes | os.PathLike, text: str) -> None: ... diff --git a/lib/matplotlib/testing/conftest.py b/lib/matplotlib/testing/conftest.py index c60a38254aad..890e922a65fd 100644 --- a/lib/matplotlib/testing/conftest.py +++ b/lib/matplotlib/testing/conftest.py @@ -24,6 +24,8 @@ def pytest_configure(config): ("filterwarnings", r"ignore:DynamicImporter.find_spec\(\) not found; " r"falling back to find_module\(\):ImportWarning"), + ("filterwarnings", + r"ignore:Glyph .* \([lp]\) missing from font\(s\) OpenMoji MplSubset\."), ]: config.addinivalue_line(key, value) diff --git a/lib/matplotlib/tests/baseline_images/test_text/colour.png b/lib/matplotlib/tests/baseline_images/test_text/colour.png new file mode 100644 index 0000000000000000000000000000000000000000..7e599d0ebd89377cda778fb96ffe9977885236b7 GIT binary patch literal 82464 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 ZK-18Y^JHA^7X$&1qO6(>RN5@`e*w5sU(o;n literal 0 HcmV?d00001 diff --git a/lib/matplotlib/tests/data/OpenMoji-color-glyf_colr_0-subset.ttf b/lib/matplotlib/tests/data/OpenMoji-color-glyf_colr_0-subset.ttf new file mode 100644 index 0000000000000000000000000000000000000000..0549ce7a1c4848f37850f2d252662daea50f459d GIT binary patch literal 24144 zcmeHv2Yg(`wf>abw(s6;YTLEDk}S!)T1hKevWjKdYHqlJ3$}5=fV)iz)$~pvl+Z#k zm<}OeY#c}eyq5&i5?X+V9ZX3=5=ekRUW|?R|IOW%EU+;oFL^J&-ycb5_s-n8Gv~~l zIdjf8b44g2#75Q=P9}Fv8aU+7SB|}tkp4}CI9}?S+&S>#-`dIvnSCBgO&mXU`k2wt zkvAg!Dk1E+NmEDGowjM`eT4MlHkrS0`GQrX?(H*?o{#h$M=tx;l3N=peva$ygmgTy zbn${kBP%`$64ISQUgJ_^nBQRw2L2Ce<>k+&9apX7i@g_s%eCD zK8Ey)C8X@$eRV&x7%WWnZ@PCE4PbhgZcfT~B z&%qU;RGPnMDW9`v+P^-ZN@({z{#c>i_x2R=$98`pSU~=H{OUsfd3#RgSMMo8ei8DW zLwq_v)AD?NQ_ufS{}_7mp5z=Huie`v=kA*dk5jsyzgy`4>-SXicXwA5=1~)`FXT7v*~#nooLm^k_xM?bd@&!- z+EZP~KW`{s%*TBG!RO;Q_56$bhi#@?*j}0=R@m+OL@cU!J-$p`V*}gkbvV3&==s@BPhH0ivOTv=8sN+Qm$Q|0$Nv4h5`F9QiT-`q z_{KH(W}Vc_cG7vofupBA z)}d3;wW^X#D5`?4W#8GqU)MOfT~%et@0Vm%wdebFRPGI|_-_**dMwr0Sj%E|7Ry8v z$*7(C(tNkdoHd7z4_1#TV^x!?v*Rjs&Li=bu9k$S+#e5=H?=p%galqv#u>SX$b`hR z*;vfaE^28x?)a9no}M1ur?=(aW7m)!Lc+LTO=e?>L>o&pa*ceMbDCGuOFXasxVF4o zPnMU8@n&b`o|T>>yWlsGc!Wo!=k_+Pr%&(N`x2r2KHPf&_e5K<7|&#+7o?j{yGhF5 z9l=KOQ`u97rUZGqu`!Y4BPe*mw~4nStUP_uOvliP&N1gPdk`w6 z{)m?Hx$JJE*2c!H&*$|hN-Ua4G}JdX_)xvi*T|bFqfS@TyyoV4O%y+!nYBl=J8%&k zpB#VOc>GBwiE(ynvDJk-Be@-HBl&<-3%$-@tWyb8Eh_idr86n~rP9!Ms5=@;VnVBS z=JWb!BcrN`GOl|nC)ZA@LZhn1qS8d~2w7g-Smcv9i&3irE?^QqA>YvIV9uic9|Jps(ALw+%C47 zd`Kz<*IA51QmAz-mdLiTg2LLFp{|*XP@DZuY zy1@k4h(uK`W|}*~*;({ytF)doX5!M`MytGDbxEOBbi=A{3$4}^MWU9yFS%42r|RBa z(9T}Eg8iCq_>#GIMW|rYYDWs2CM#jO;y`on`{b{DEgM5Hf#P+I7`{T^4$~OXYhp^n zKKs~Z?Mp^e43}!AEHk5_eny5;h;OBA^pSt`wQIi(+(jQj_{ANv*uC%+|c8_MUXdZD@De^S4KTzq{ zbw8Nmepbf6&32HG;1DX3fb@pC`FyIlMo;+sPX86&OO zdl#a((|>##!5#K6BT(%=%;EMA+B)w=PMi_85;+dio|{XM2kmIi?UYR9H^wZ#`x;q5q!kN>g@Omm&C&fu@D5)VjbvcLLf`oL%EM6H+hp_IgZx_xspyr zW3@cl#`t0R#Us`t+iMoiir3e^8EYKf7%Ll97v-`OD;hr=cKryFBOW}P@v14sml-8N z;}Yp)LxykljHj}hCmS1*+$_`azTEK}Y*wpn!|_6M^3R?p{FC_Sp5)Jd{;~7&58)Yl z2YrfPz|J&gu|MU5MGdmXbT*N&GkVALSf*ZgH8&@E`Y%3lPCe^Cl~cQ}+bLf;qD(9H zfHd7D%fYSK*HJZK1>rSWW^c9^tW$M_F zR8*uDm1|Z<*YraZUG40qP+hq@9*)^%XIN)#@uEhvuc2ph!t3;u$iC9*$!PJX)WjFD z5@T)2VxcxxmHGx)&O!G1m?&$Wn;ms{lgv|tBG6|Wx>t9NJFbVTTw>z~1rdF)ht1(V z>`5`|R46;v7NZ}s{vh+GJiKSjNk=6lEKH2*W0p;&lGn@FoKmaJQkFI|PW6COwwo}E z4G3TpEZPYyO-fN4tXV7}W=afR9}J7(wE5v?W*hkll59dRG-vxKG&Spb=a_kO$8<1m zmSpNaVr*CU_{DBrcdwZ;b@D{;xQ(UwulPC=N3EEKn1h&cs5#{wN{O_v>SE@?HmsEy z(_C8DLjy|}CQF>jE5|K&Gb+obqq7DL>pqt8!V(1`Wsny$u@~flF1~?RAMV!vh1p^ z5DAePM-6APHu~Q@V)%Ck?|B*MAFXzWWgw!sbfuK-v0E+nxktKW#RUw7zL49_{sU`% zu~?bbfKxF-xGzFn)GP9c-gw@{Xejo|oR>4JN~86oiblf6hz0E^g|aRl zh`_Ufw^7#BTET?Z$JgY3C>={(qyZcXMM)&qG`X9z4%sO?>N50Uv&(K}64h2<5tOQfYDqDbG)+B4VLY+eRATWZ zW-zNmmYo&~yWdAwvNz~0WIXAVlcfAHEPKe^$|&coU#t%wwj1k1f>E{#IbwY{oFEU{ zb2**EuS9Gm2FmbO5>N@Ojqpq|yuU1LZ(TF>khQJ$a2cJ`e_Tg)aYx7EY{zl^C{CMl zTlfcLqlkxO3|k_mB*mj%{z1dE+Kn4)r#1BU*7jFla6xr{Z7<57PW$-n2psr|j?QM;(m7??D7!i;Mr+%rjcZCZHTDlQWa*A|lO|7| zymtN?v)kjAZS#(pGR5g}vPDyujO*&^#`?RJK7+O1w_oJRnTR??^hrM)9(g9{Gw=lV zFVFTxs>93EC&_kxIJ?4FFX|f`)4n#ANd?(pj6=5tN~=b<4rHA^S88@=`|K3mQPW>z zr%p$xp)=aIuB&SuxEzmI{!O}C%&C05o41D|;&rK9cDxH+!QcVg-7fO8i*1 z-SCnXICUvISCjdLv;YGn`I054jxCiep5kH)r7a6vM=u z;9?orfmgU^-aK}IJk=tw1GigX2lN5v<43aJ6A^~i34}=m3Wmd`il{7+NDHqWZk8$> zMfy{jJA$P^Qo8@Fnyu=*)uXHyPMuEK8Z0vbl9ri|skJR7l=T@cQOQ|qu{xa+ca)E> z!>4K%y7haqO{(M8MOn_LzTM4o(xMz+%REUlyPsw!6Z|C zIVJZaJ;6wynR{M(mVAcvB$4L#BK^FPo^0HIm?2nT6AUz|vk)zCL<lSTA1;G(dp_fB;}t_~MC|w*~?B^d^Dw#sLxt zeAmT~LLiMkrUi5;xsUhO8rpPtbJN^rS~JKKeQMnJwcTUajO!YLgedFJeT>=BEOaQI z2W_B5Y?T0HlDZzjMjNH~1Ls-C8jKaph-*bqdjOngEj551E!)^L2=pA**-k$&un~Q3 zTU&R}Vn487AU(Z3sJ9ph#m&GxDxkj@0AWK#eB`goq%&!3d>A$znIb+D&53Us#nd+G z%;X9me+1%tjL_I4szM@u5Lm?A*4D#i`MZ^Fk4fT`>)EEItb?%*Y6DKLxp;d!KMUY5 z=PR*Ku!ibn1gRxyp{1BQdCbbM#tgVYBr&H9tikVVVX$`wKHQ`!7^Wil?h%ds=W==-|ceVioSOgC`pc(+?$a06pzQ(2iA3(*Y=_Wp%Z zjCK=i;ValHL@aAq2aFyt`T__-Ds2eOdR?mG8ectToKq86*Z8qw1S;7@h?A7EcxT+? z)S#A$ajGiz?I)9u_%?nEsX>i{{hC7biC?iWI zMF$vSicS#WK8W5(otEj6wltevXOenM&YQQ+DbDoVa!J!MNvo}54m-@^I7OwdilmdO zE1l*!0Y`I@wPawXEn%}I?Xa$uxi|PO@(yO|{10-lp6heZNOOV7D`eqrr0E9wbAA?E zkMyEXKZEt%Ompz(dxbUq(`dt*#%K=lY_DNWXOnzh5B8gO&<)t1?k9U-54Ql5s)DYH z-S8nh&!2L;CqVCXF;#JchRH@L!snBA^sh0pV!R7;s!^aR;@9i(8sGayA3BZk7gI~* z74)DNqhXFJQqZb68MnDRJEza8lC?TOKnbf_GuGm8m=9^xtTAOoRcphNd3_UoSTSvi zH6&{fIn8EAwkg_GY9G)zmWA(zzI1`^ppbvI$4Er)spORNa(@ z@hvfXNl(RCVZk3JPXkGL3CNScgFO3y6v3O?;5q zbv|@a2H`;vejF}+3L1vHmQ<4BD?$6Hra8S1*&}niwQE6h^{4=qwMa(=H#zN!MRuD^ zx@IeNlvmz!cX7t=j6J~0TgQ(n(mmO1OSXD!qNs=}yu3M@ZL0~|{MPWq-i&1Rnv3}b z7ch^@g544N0{Ihm?;aF8E7aIO%?{gIrZ4cyY*FpO2XE3S%F&fRzZp3u`IXRCYx)`1zB7K|0?7zyc@Mii?dCYm#vy z>2mB1iG3)s4jOP7&a6f4*nu$iq2eJW(6*qvdqG=33B_sOm}MQQIejBW^vy|iEE54B z_LiEs*jp02_QJ>CZ*OVeCXE-qhOxhtZ9n0J_AIt|I&^bK-}&eFb(nS9r0d%kb@ugj zF50f^(`!#z(?4TI|C&>3r;ApWVV{Jur^UHCD)vdRVq=?R9~wuOna$ZrUGbu1jmO65K)btPSSGC;pW&2fC?7|CK)qeX`l)RQ}kS?QV zh*Nd6A>zfc&dc`n@P}z)&YZmtAYH$sr%NaE=fsIT+CaV1$$O5Wr$0om-i&)M=VH<& zw8TM!gm786@xo? zsuWKp#lg}`^gYKI&z0k7_$vOKu79=(Q4>p|U((bhWoYe?4~%Dkb#&o8=ngo+wFtCO zKa1p+^3g=>yrX{X_ZiWJ2;}@3Z;VCszv=iZfAPh0bp1-;Bdfp!d6%9sBq=0;q|4|T zY~Zs^uoP)>io@K(j-@pr?=#8l~(h^jVQc+P&b2cBHNg>y6?<; z7cRW_%)Y^IdiwAba?w70gSPW|+(88NA%fm)o0P^@crq2kT;Z53m@TJqrb@l6G#M|E zB;{hNIHYGdS1*=mJ5x{MH686$IO#M4h}7PD#05jd^d{TPyLpK*f~r5um3Vucm$W6? z&}KHbjsF@ul^ET)H_||}?DqJaIbeW&N>=grfbM{sxHun$Gor}^JZ}UCK+5rnUH8p) zNh`C|j}I%FCRLd2zPh;Tm1O%EX_d8P=0(R06aiCITkRHSUMY^cgG&&oFD^BSr;N>X#J)=L3fGwF4sDQx(;uAL43aH0q zrB+GNO|rtR<#9UGj!cV2aWoL;54fqqFWv%q4Ksfc_dpv6&BwWF(v8s12(eLPGMY}H ze{q-wAtHMfENf0v$BL~hR1;2-DYDb#xR^T3&zPJSJ5BUI#PJc6V_6q%=(0Ef(lWKw zX_{ej?!CwO61-QFKK3+iHg+m};s^lZT(rlocWDmQwfANmSkqinRA@--UIndfHq9pblyMrIjGliLCw1z%H zYuT({K$gE#|`hFy++(<`EdiI%XdnnFj$x} zhzPMa`woIUOKELQqQi9&THyHBz`hs3xygVK+XLU&VyrEv?mzT#8KRru#^A>g# zanP|iWv8eM!5a`qzKTAz{|@}Bu-_jRL@yWLzDPtY4)k2w$nWKSB#DHv9^tgq&}jz& zbLF`jJUC#iNpHE`QL8E2al-K(S(7zttV^AJ=V4vKv8qPh-BfkrqK>}4jzuR{HMy}i zow~Yz=FI-pr{>qDZN?t{(+0jYY;8&nZ57dN2UwhHQpVyGtgZ9bRpu8b!s!+ufvdR- zs98Jdh6IDrxiP=;b5s>bLP|}=Qr=WLm5zF`;EP|sICvp`vHGip6A+MHthrm-+vXkK zhEwsBH}+cW7T>bN(62!D#1D2R%yEse!&jNL&Ww{bWhP9_G}5ED71Ml(rgP(THzfzW__KD+=z;-tXky zpTFeKEDjxE{>G=CM&Vv3WKNspM8!gyeh zwSa`z)9rDn@vOEEIW9HT^+88jF}A&+qGQJ&N0*LnYVBN&7b_Wkl=bt)m_sAQxi{() z#;`DR(rL_{81|(1n>#3#pF6UcF&^F~HazlkW%;3;4{5zDiQ|d+$GKxjEYv&Dib_a0Xd?`qu^{O_djM-Ngyj|NfQPX` z(G;mTZk}(&}Ow7KxEO)Xunxtv-kBtFF%-@ohR8fJ3ATZe@hWt_dY-s; zO`GUgI+@O)OX)hgo?b++rnl1j>7(>X`V!qq-=lwH5_7ULR>A672OD6AvPC#UaWXrP zUBPZ*_aK`1Pxec;oqf!8-oSehw=U!BINqPe`%1U+AM-aQS@KFXQj63l&66&WHc21K z4*3xIWcfz<6{SL%ul!7TQQ5BiRyC&ob3A+p^TM+H#WR9Lu*Y*H|`K?y@{+ zdBpOh<$25Nmfu?bY}sXHR+SINcqe-g_0IPm%F&m@AE$H-R6DX`?mLw-oJQv`?$~Q^ZA0lgs;}u=xg`&`lk36`IhH5<1O21Qjed(>G_muv&%v6>tJGJbVvJc8W4M+iNz!R7mSRFV&a9QBGz{bG6 zfrkP=32X~IA9yYBcHsTMCxOp`-e4e@45ow4!OmcRaC&fVaB*;D@LR#tgXaft4&E7j zF!-b3PlL|}UkSb${C)7l;O>wdvW2{%novWiJ=7bT5;`ojFtj{$Z0MBGxuMHK*Mx2k zZ4EshdOGxSXh-Nbp+ARqg=yFnc83Guc(^9q9i9-L8D4f25@+5Kb&W6`7%DuPu9%ZL=J(3C#MB_)=E&eYFBDV_i^2plo^5slDS=#^|4-Xr}!{6jxI zlirCLAE(XiA$~SL8*ipvi+8>D&`pRicjE2~G|JcTAL5xlysd$^%VA$m$J?k68L21P zczEjNg7Wp`Oa068Hj*69us%Sa#+lRK!`l6dUcrt5&&|xk&gAz(k_0$-l%GZCK=!9t zKP+D{U&)$a5w{_A39aPoahhQ>i?JTQ1vNZOTOeZ`9{Lw*`9jHmqY~K7xEy1!jK;}p zI8FC5knA*z06R_tBi=&aU~dAq{FFTj{PH!d2XWwYud!>`E*@czuxAlpor|&ELhnQ^ z+b~jb=)xJe-iinsQ7>Y`!MrW#l_oro-WpzZ=>GrFJxn&tQ^_k{s*x)&Cwr8gL+hn6 zC-K3FBv;T&v8N!hYuOUyOvr!JB_uCt#VJj)iYz88 z$ON*I98HdbtapNX$P&Ee6~?*bg=8sCd%Q!Az`eCbDvUeJagJyOWDb)q{MO)Xgbj}vgI1JpYKEiFTtV^P;yw7CvXu0+mCvSz>1`l4xl2Up!+AE`LkrSZjASXz# zLr#d^ikvXeDKCl8XOI)6FC!;L-$hP2{R}yAod0o?1S>{Pl8GI(3YJAqCF?^@6`O~g z5o{?Wsb*`yYYqMbgidPl)|Z=%#A!McNwNEplV(pKr;fdhoDBOla_ZR!$Z6mlIgQ+k zoGcF_r-`SL)67R9XA~bmP74>UwDP6M8O={bP8+`%IbG9YUmgy5 zG{~coOYq#+8J};X+@+wrJRI_9c#n{f?|_EOb2-vifDSGXfjk8ADErBCCGxKVeHZlg z<9f zJa+u2qpv5=y(o7dC@+r{<6|e^NBVxy@bUQp(hq0`yDJ^Pm?%FM@ zDD!qfhIi2ZZwwjikikrTi~GL=y$kv(8Qw&h-w%`F50K%Hh75MdV1^84Lx%TI?tRdo zK*MGDGtyr!gB>!M4H-T_x#2Q=i1c63&c_8AK7kB>HDutBLBq*)LjDHY1^Ox(K0=vK zhsm%TGVC#A;E+Ls44NUsXDGK9lmiWufg*Vj88~Fngba9p;Bzv-lYrYuBr4}+fWK(M zcBjxK0vQyl;XXW4Dm>}0kb!cP6X$3Oxb@w-CJ7M5q&W4wu1& z^p}qVfeeZvgN|~;#zFY~)C(DW1sVL1p=d}3PK$BB1XTJpWbmL|*)SObkRdoE1BVRU zkRgO}VNe8h4woT{^ucA|h72*38!kgR>PkR{WI=`s$WUp>Am+54R^k2#P&Jk&L2Gj-W0ExVA$Ttq^I3C|UplP@k|Jk7r_xeEtpb4Ofph=*~pedk3KvU7~0sJ94 z3;H@6_GTLH5A*HlVR&W^XfEh*&^*wgC^HLm0KbmTM?DLOjUIuzmZ8jY&JhudN zBnWF2g|9~!f);@mgO*|ZvUqkTo^3)J&rv)_#dAl4jzJv<;(HawcQtIxf%sm7=hlMO zfsO?ooNqh$HiK{TetaK?XO9P+0D|6qj_(r1;9D{H{x0rc z4Y~$&Fut$F{p(P~IOh@XueH!zLZ zmn~Sg0(?uz$D20BeY$Yr@>S6Jd})e%;x0uFMbym^(LaIt>Ow8Gq=}4y?U+I4Bf4CN zXz@HmDObZ|zZG8U{qPk8?m&SrX@#q5v@W3zk!LAfRl}Z%HbkD_L|j!vW(n(z$a590 zsu68V&}ot9DO^?Kq;kGCzwuoSUq>JwRuIQpBd`x~URMS}!0_zX;kp>l>Tvd}Y zT;Qo!-cDAystONb*ykzjnk=vTw^6Q_^-yBqWRh?3tX3?MFuoRa2>&? zgx(cgC-M39xURu7d9G^rX$QF;Rk*6g lK4PBh(FLwYqD3Zj3F!uWO3(+vbqhYlIB`-0oDu8l{{!=SPcZ-h literal 0 HcmV?d00001 diff --git a/lib/matplotlib/tests/test_text.py b/lib/matplotlib/tests/test_text.py index dad82f6af4fb..13bb8333633a 100644 --- a/lib/matplotlib/tests/test_text.py +++ b/lib/matplotlib/tests/test_text.py @@ -2,6 +2,7 @@ import gc import inspect import io +from pathlib import Path import warnings import numpy as np @@ -1331,3 +1332,37 @@ def test_draw_text_as_path_fallback(monkeypatch): _test_complex_shaping(subfig[0]) _test_text_features(subfig[1]) _test_text_language(subfig[2]) + + +@image_comparison(['colour.png'], remove_text=False, style='mpl20') +def test_colour_fonts(): + zwj = '\U0000200D' + adult = '\U0001F9D1' + man = '\U0001F468' + woman = '\U0001F469' + science = '\U0001F52C' + technology = '\U0001F4BB' + skin_tones = ['', *(chr(0x1F3FB + i) for i in range(5))] + + text = '\n'.join([ + ''.join(person + tone + zwj + occupation for tone in skin_tones) + for person in [adult, man, woman] + for occupation in [science, technology] + ]) + + # To generate the subsetted test file, save the latest + # OpenMoji-color-glyf_colr_0.ttf from + # https://github.com/hfg-gmuend/openmoji/tree/master/font to the data directory, + # set this condition to True, and run the test. + path = Path(__file__).parent / 'data/OpenMoji-color-glyf_colr_0.ttf' + if False: + from matplotlib.testing import _generate_font_subset + _generate_font_subset(path, text) + path = path.with_stem(path.stem + '-subset') + if not path.exists(): + pytest.xfail(f'Test font {path} is not available') + + fig = plt.figure() + fig.text(0.5, 0.5, text, + font=FontProperties(fname=path), fontsize=48, linespacing=0.9, + horizontalalignment='center', verticalalignment='center') From a8725236fc8c5f558882d6e91454fb22b10ae54b Mon Sep 17 00:00:00 2001 From: Elliott Sales de Andrade Date: Sat, 28 Feb 2026 00:00:58 +0530 Subject: [PATCH 3/3] DOC: Add a note about colour font support --- doc/release/next_whats_new/colour_font.rst | 33 ++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 doc/release/next_whats_new/colour_font.rst diff --git a/doc/release/next_whats_new/colour_font.rst b/doc/release/next_whats_new/colour_font.rst new file mode 100644 index 000000000000..1e5e16716310 --- /dev/null +++ b/doc/release/next_whats_new/colour_font.rst @@ -0,0 +1,33 @@ +Support for (some) colour fonts +------------------------------- + +Various colour fonts (e.g., emoji fonts) are now supported. Note, that certain +newer, more complex fonts are `not yet supported +`__. + + +.. plot:: + + from pathlib import Path + from matplotlib.font_manager import FontProperties + + zwj = '\U0000200D' + adult = '\U0001F9D1' + man = '\U0001F468' + woman = '\U0001F469' + science = '\U0001F52C' + technology = '\U0001F4BB' + skin_tones = ['', *(chr(0x1F3FB + i) for i in range(5))] + + text = '\n'.join([ + ''.join(person + tone + zwj + occupation for tone in skin_tones) + for person in [adult, man, woman] + for occupation in [science, technology] + ]) + + path = Path(plt.__file__).parent / 'tests/data/OpenMoji-color-glyf_colr_0-subset.ttf' + + fig = plt.figure(figsize=(6.4, 4.8)) + fig.text(0.5, 0.5, text, + font=FontProperties(fname=path), fontsize=48, linespacing=0.9, + horizontalalignment='center', verticalalignment='center')