From 88a664e55cf8d6579907c6aedc282b3c1a7bc8ab Mon Sep 17 00:00:00 2001 From: Michael Droettboom Date: Fri, 23 Oct 2015 12:08:14 -0400 Subject: [PATCH 01/17] Use a specific version of Freetype for testing This should theoretically allow us to turn down the tolerance on image comparison tests. --- .gitignore | 1 + .travis.yml | 6 ++- doc/devel/testing.rst | 27 ++++++---- lib/matplotlib/__init__.py | 11 ++++ setup.cfg.template | 7 +++ setup.py | 14 ++++- setupext.py | 102 +++++++++++++++++++++++++++++-------- src/ft2font_wrapper.cpp | 9 +++- 8 files changed, 140 insertions(+), 37 deletions(-) diff --git a/.gitignore b/.gitignore index 679c9b957873..722a42ec6185 100644 --- a/.gitignore +++ b/.gitignore @@ -39,6 +39,7 @@ dist .eggs # tox testing tool .tox +setup.cfg # OS generated files # ###################### diff --git a/.travis.yml b/.travis.yml index c01cd8b337d2..7e378b40e8bc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -75,7 +75,7 @@ install: # version since is it basically just a .ttf file # The current Travis Ubuntu image is to old to search .local/share/fonts so we store fonts in .fonts - # We install ipython to use the console highlighting. From IPython 3 this depends on jsonschema and misture. + # We install ipython to use the console highlighting. From IPython 3 this depends on jsonschema and mistune. # Neihter is installed as a dependency of IPython since they are not used by the IPython console. - | if [[ $BUILD_DOCS == true ]]; then @@ -90,6 +90,10 @@ install: cp Felipa-Regular.ttf ~/.fonts fc-cache -f -v fi; + + # Use the special local version of freetype for testing + - echo '[test]\ntesting_freetype = True' > setup.cfg + - python setup.py install script: diff --git a/doc/devel/testing.rst b/doc/devel/testing.rst index ddce97568e71..0cc5aabcc392 100644 --- a/doc/devel/testing.rst +++ b/doc/devel/testing.rst @@ -33,6 +33,22 @@ Optionally you can install: - `pep8 `_ to test coding standards +Build matplotlib for image comparison tests +------------------------------------------- + +matplotlib's test suite makes heavy use of image comparison tests, +meaning the result of a plot is compared against a known good result. +Unfortunately, different versions of freetype produce differently +formed characters, causing these image comparisons to fail. To make +them reproducible, matplotlib can be built with a special local copy +of freetype. This is recommended for all matplotlib developers. + +Add the following content to a ``setup.cfg`` file at the root of the +matplotlib source directory:: + + [test] + testing_freetype = True + Running the tests ----------------- @@ -185,17 +201,6 @@ decorator: If some variation is expected in the image between runs, this value may be adjusted. -Freetype version ----------------- - -Due to subtle differences in the font rendering under different -version of freetype some care must be taken when generating the -baseline images. Currently (early 2015), almost all of the images -were generated using ``freetype 2.5.3-21`` on Fedora 21 and only the -fonts that ship with ``matplotlib`` (regenerated in PR #4031 / commit -005cfde02751d274f2ab8016eddd61c3b3828446) and travis is using -``freetype 2.4.8`` on ubuntu. - Known failing tests ------------------- diff --git a/lib/matplotlib/__init__.py b/lib/matplotlib/__init__.py index dbd2f56aa453..ef10fd6518f6 100644 --- a/lib/matplotlib/__init__.py +++ b/lib/matplotlib/__init__.py @@ -1499,6 +1499,17 @@ def _init_tests(): if not os.path.isdir(os.path.join(os.path.dirname(__file__), 'tests')): raise ImportError("matplotlib test data is not installed") + # The version of freetype to install locally for running the + # tests. This must match the value in `setupext.py` + LOCAL_FREETYPE_VERSION = '2.5.2' + + from matplotlib import ft2font + if (ft2font.__freetype_version__ != LOCAL_FREETYPE_VERSION or + ft2font.__freetype_build_type__ != 'local'): + raise ImportError( + "matplotlib is not built with the correct freetype version to run " + "tests. Set local_freetype=True in setup.cfg and rebuild.") + try: import nose try: diff --git a/setup.cfg.template b/setup.cfg.template index 9d50b4441582..e5ea29b5163c 100644 --- a/setup.cfg.template +++ b/setup.cfg.template @@ -8,6 +8,13 @@ # This can be a single directory or a comma-delimited list of directories. #basedirlist = /usr +[test] +# If you plan to develop matplotlib and run or add to the test suite, +# set this to True. It will download and build a specific version of +# freetype, and then use that to build the ft2font extension. This +# ensures that test images are exactly reproducible. +#local_freetype = False + [status] # To suppress display of the dependencies and their versions # at the top of the build log, uncomment the following line: diff --git a/setup.py b/setup.py index e2a6393bc406..827749ae24e5 100644 --- a/setup.py +++ b/setup.py @@ -9,6 +9,7 @@ from distribute_setup import use_setuptools use_setuptools() from setuptools.command.test import test as TestCommand +from setuptools.command.build_ext import build_ext as BuildExtCommand import sys @@ -239,8 +240,19 @@ def run_tests(self): argv=['nosetests'] + self.test_args, exit=True) + +class BuildExtraLibraries(BuildExtCommand): + def run(self): + for package in good_packages: + package.do_custom_build() + + return super(BuildExtraLibraries, self).run() + + cmdclass = versioneer.get_cmdclass() cmdclass['test'] = NoseTestCommand +cmdclass['build_ext'] = BuildExtraLibraries + # One doesn't normally see `if __name__ == '__main__'` blocks in a setup.py, # however, this is needed on Windows to avoid creating infinite subprocesses @@ -303,8 +315,6 @@ def run_tests(self): # Now collect all of the information we need to build all of the # packages. for package in good_packages: - if isinstance(package, str): - continue packages.extend(package.get_packages()) namespace_packages.extend(package.get_namespace_packages()) py_modules.extend(package.get_py_modules()) diff --git a/setupext.py b/setupext.py index 2c3bd1fa8cc5..f1c22ab72937 100755 --- a/setupext.py +++ b/setupext.py @@ -20,6 +20,12 @@ PY3 = (sys.version_info[0] >= 3) +# This is the version of freetype to use when building a local version +# of freetype. It must match the value in +# lib/matplotlib.__init__.py:validate_test_dependencies +LOCAL_FREETYPE_VERSION = '2.5.2' + + if sys.platform != 'win32': if sys.version_info[0] < 3: from commands import getstatusoutput @@ -47,22 +53,19 @@ config = configparser.SafeConfigParser() config.read(setup_cfg) - try: + if config.has_option('status', 'suppress'): options['display_status'] = not config.getboolean("status", "suppress") - except: - pass - try: + if config.has_option('rc_options', 'backend'): options['backend'] = config.get("rc_options", "backend") - except: - pass - try: + if config.has_option('directories', 'basedirlist'): options['basedirlist'] = [ x.strip() for x in config.get("directories", "basedirlist").split(',')] - except: - pass + + if config.has_option('test', 'local_freetype'): + options['local_freetype'] = config.get("test", "local_freetype") else: config = None @@ -448,6 +451,14 @@ def _check_for_pkg_config(self, package, include_file, min_version=None, return 'version %s' % version + def do_custom_build(self): + """ + If a package needs to do extra custom things, such as building a + third-party library, before building an extension, it should + override this method. + """ + pass + class OptionalPackage(SetupPackage): optional = True @@ -461,10 +472,9 @@ def get_config(cls): if the package is at default state ("auto"), forced by the user (True) or opted-out (False). """ - try: - return config.getboolean(cls.config_category, cls.name) - except: - return "auto" + if config is not None and config.has_option(cls.config_category, cls.name): + return config.get(cls.config_category, cls.name) + return "auto" def check(self): """ @@ -872,6 +882,9 @@ class FreeType(SetupPackage): name = "freetype" def check(self): + if options.get('local_freetype'): + return "Using local version for testing" + if sys.platform == 'win32': check_include_file(get_include_dirs(), 'ft2build.h', 'freetype') return 'Using unknown version found on system.' @@ -917,15 +930,60 @@ def version_from_header(self): return '.'.join([major, minor, patch]) def add_flags(self, ext): - pkg_config.setup_extension( - ext, 'freetype2', - default_include_dirs=[ - 'include/freetype2', 'freetype2', - 'lib/freetype2/include', - 'lib/freetype2/include/freetype2'], - default_library_dirs=[ - 'freetype2/lib'], - default_libraries=['freetype', 'z']) + if options.get('local_freetype'): + src_path = os.path.join( + 'build', 'freetype-{0}'.format(LOCAL_FREETYPE_VERSION)) + # Statically link to the locally-built freetype. + # This is certainly broken on Windows. + ext.include_dirs.insert(0, os.path.join(src_path, 'include')) + ext.extra_objects.insert( + 0, os.path.join(src_path, 'objs', '.libs', 'libfreetype.a')) + ext.define_macros.append(('FREETYPE_BUILD_TYPE', 'local')) + else: + pkg_config.setup_extension( + ext, 'freetype2', + default_include_dirs=[ + 'include/freetype2', 'freetype2', + 'lib/freetype2/include', + 'lib/freetype2/include/freetype2'], + default_library_dirs=[ + 'freetype2/lib'], + default_libraries=['freetype', 'z']) + ext.define_macros.append(('FREETYPE_BUILD_TYPE', 'system')) + + def do_custom_build(self): + # We're using a system freetype + if not options.get('local_freetype'): + return + + src_path = os.path.join( + 'build', 'freetype-{0}'.format(LOCAL_FREETYPE_VERSION)) + + # We've already built freetype + if os.path.isfile(os.path.join(src_path, 'objs', '.libs', 'libfreetype.a')): + return + + tarball = 'freetype-{0}.tar.gz'.format(LOCAL_FREETYPE_VERSION) + tarball_path = os.path.join('build', tarball) + if not os.path.isfile(tarball_path): + print("Downloading {0}".format(tarball)) + if sys.version_info[0] == 2: + from urllib import urlretrieve + else: + from urllib.request import urlretrieve + + urlretrieve( + 'http://download.savannah.gnu.org/releases/freetype/{0}'.format(tarball), + tarball_path) + + print("Building {0}".format(tarball)) + subprocess.check_call( + ['tar zxf {0}'.format(tarball)], shell=True, cwd='build') + subprocess.check_call( + ['./configure --without-zlib --without-bzip2 --without-png'], + shell=True, cwd=src_path) + subprocess.check_call( + ['make'], shell=True, cwd=src_path) class FT2Font(SetupPackage): diff --git a/src/ft2font_wrapper.cpp b/src/ft2font_wrapper.cpp index 9bcb2e73d3a5..e176110627df 100644 --- a/src/ft2font_wrapper.cpp +++ b/src/ft2font_wrapper.cpp @@ -7,6 +7,9 @@ // From Python #include +#define STRINGIFY(s) XSTRINGIFY(s) +#define XSTRINGIFY(s) #s + static PyObject *convert_xys_to_array(std::vector &xys) { npy_intp dims[] = {(npy_intp)xys.size() / 2, 2 }; @@ -1759,7 +1762,7 @@ PyMODINIT_FUNC initft2font(void) int error = FT_Init_FreeType(&_ft2Library); if (error) { - PyErr_SetString(PyExc_RuntimeError, "Could not find initialize the freetype2 library"); + PyErr_SetString(PyExc_RuntimeError, "Could not initialize the freetype2 library"); INITERROR; } @@ -1774,6 +1777,10 @@ PyMODINIT_FUNC initft2font(void) } } + if (PyModule_AddStringConstant(m, "__freetype_build_type__", STRINGIFY(FREETYPE_BUILD_TYPE))) { + INITERROR; + } + import_array(); #if PY3K From 733cda978dd19d3555d7cc176bb62b4186225cf8 Mon Sep 17 00:00:00 2001 From: Michael Droettboom Date: Fri, 23 Oct 2015 12:51:53 -0400 Subject: [PATCH 02/17] Python 2 fix --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 827749ae24e5..3e1393e8a6d3 100644 --- a/setup.py +++ b/setup.py @@ -246,7 +246,7 @@ def run(self): for package in good_packages: package.do_custom_build() - return super(BuildExtraLibraries, self).run() + return BuildExtCommand.run(self) cmdclass = versioneer.get_cmdclass() From 56c686e61cfea1742e7182c9f8a974181eba8f7d Mon Sep 17 00:00:00 2001 From: Michael Droettboom Date: Fri, 23 Oct 2015 13:23:29 -0400 Subject: [PATCH 03/17] Fix setup.cfg in .travis.yml --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 7e378b40e8bc..9d354b43e179 100644 --- a/.travis.yml +++ b/.travis.yml @@ -92,7 +92,7 @@ install: fi; # Use the special local version of freetype for testing - - echo '[test]\ntesting_freetype = True' > setup.cfg + - echo '[test]\nlocal_freetype = True' > setup.cfg - python setup.py install From 924950e6c9f000f8bfc5805a705c77a4930ae964 Mon Sep 17 00:00:00 2001 From: Michael Droettboom Date: Fri, 23 Oct 2015 13:31:44 -0400 Subject: [PATCH 04/17] Generate setup.cfg in a different way --- .travis.yml | 2 +- .travis/setup.cfg | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 .travis/setup.cfg diff --git a/.travis.yml b/.travis.yml index 9d354b43e179..7da9e5c8ad4c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -92,7 +92,7 @@ install: fi; # Use the special local version of freetype for testing - - echo '[test]\nlocal_freetype = True' > setup.cfg + - cp .travis/setup.cfg . - python setup.py install diff --git a/.travis/setup.cfg b/.travis/setup.cfg new file mode 100644 index 000000000000..61cdc102a0f8 --- /dev/null +++ b/.travis/setup.cfg @@ -0,0 +1,2 @@ +[test] +local_freetype=True \ No newline at end of file From bab2d6a67e77446d681267a7487e9bb6c87cfc1f Mon Sep 17 00:00:00 2001 From: Michael Droettboom Date: Fri, 23 Oct 2015 13:47:21 -0400 Subject: [PATCH 05/17] Use -fPIC --- setupext.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setupext.py b/setupext.py index f1c22ab72937..482b59dac37c 100755 --- a/setupext.py +++ b/setupext.py @@ -980,10 +980,10 @@ def do_custom_build(self): subprocess.check_call( ['tar zxf {0}'.format(tarball)], shell=True, cwd='build') subprocess.check_call( - ['./configure --without-zlib --without-bzip2 --without-png'], + ['CFLAGS=-fPIC ./configure --without-zlib --without-bzip2 --without-png'], shell=True, cwd=src_path) subprocess.check_call( - ['make'], shell=True, cwd=src_path) + ['CFLAGS=-fPIC make'], shell=True, cwd=src_path) class FT2Font(SetupPackage): From 7935fa15ff62cf5d3953c3387f32397dd1cf4685 Mon Sep 17 00:00:00 2001 From: Michael Droettboom Date: Fri, 23 Oct 2015 14:35:26 -0400 Subject: [PATCH 06/17] Don't use special freetype in docs build --- .travis.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 7da9e5c8ad4c..47931f7680ff 100644 --- a/.travis.yml +++ b/.travis.yml @@ -89,11 +89,11 @@ install: cp tmp/usr/share/fonts/truetype/humor-sans/Humor-Sans.ttf ~/.fonts cp Felipa-Regular.ttf ~/.fonts fc-cache -f -v + else + # Use the special local version of freetype for testing + cp .travis/setup.cfg . fi; - # Use the special local version of freetype for testing - - cp .travis/setup.cfg . - - python setup.py install script: From ca61716cf3cb2570220fb9b17a654b1105531d09 Mon Sep 17 00:00:00 2001 From: Michael Droettboom Date: Sat, 24 Oct 2015 09:07:31 -0400 Subject: [PATCH 07/17] Verify hash of freetype tarball --- setupext.py | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/setupext.py b/setupext.py index 482b59dac37c..d488383e2bc1 100755 --- a/setupext.py +++ b/setupext.py @@ -24,7 +24,8 @@ # of freetype. It must match the value in # lib/matplotlib.__init__.py:validate_test_dependencies LOCAL_FREETYPE_VERSION = '2.5.2' - +# md5 hash of the freetype tarball +LOCAL_FREETYPE_HASH = '004320381043d275c4e28bbacf05a1b7' if sys.platform != 'win32': if sys.version_info[0] < 3: @@ -222,6 +223,21 @@ def make_extension(name, files, *args, **kwargs): return ext +def get_file_hash(filename): + """ + Get the MD5 hash of a given filename. + """ + import hashlib + BLOCKSIZE = 1 << 16 + hasher = hashlib.md5() + with open(filename, 'rb') as fd: + buf = fd.read(BLOCKSIZE) + while len(buf) > 0: + hasher.update(buf) + buf = fd.read(BLOCKSIZE) + return hasher.hexdigest() + + class PkgConfig(object): """ This is a class for communicating with pkg-config. @@ -966,15 +982,18 @@ def do_custom_build(self): tarball = 'freetype-{0}.tar.gz'.format(LOCAL_FREETYPE_VERSION) tarball_path = os.path.join('build', tarball) if not os.path.isfile(tarball_path): - print("Downloading {0}".format(tarball)) + tarball_url = 'http://download.savannah.gnu.org/releases/freetype/{0}'.format(tarball) + + print("Downloading {0}".format(tarball_url)) if sys.version_info[0] == 2: from urllib import urlretrieve else: from urllib.request import urlretrieve - urlretrieve( - 'http://download.savannah.gnu.org/releases/freetype/{0}'.format(tarball), - tarball_path) + urlretrieve(tarball_url, tarball_path) + + if get_file_hash(tarball_path) != LOCAL_FREETYPE_HASH: + raise IOError("{0} does not match expected hash.".format(tarball)) print("Building {0}".format(tarball)) subprocess.check_call( From 662ae7d89d62fd90e37870c9b6d20bba51e9196a Mon Sep 17 00:00:00 2001 From: Michael Droettboom Date: Mon, 26 Oct 2015 12:49:46 -0400 Subject: [PATCH 08/17] Change error to warning --- lib/matplotlib/__init__.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/matplotlib/__init__.py b/lib/matplotlib/__init__.py index ef10fd6518f6..06ad93643dd5 100644 --- a/lib/matplotlib/__init__.py +++ b/lib/matplotlib/__init__.py @@ -1506,9 +1506,10 @@ def _init_tests(): from matplotlib import ft2font if (ft2font.__freetype_version__ != LOCAL_FREETYPE_VERSION or ft2font.__freetype_build_type__ != 'local'): - raise ImportError( + warnings.warn( "matplotlib is not built with the correct freetype version to run " - "tests. Set local_freetype=True in setup.cfg and rebuild.") + "tests. Set local_freetype=True in setup.cfg and rebuild. Expect " + "many image comparison failures below.") try: import nose From d102d39d56c43bfa51bb1ee5a5548522f40abeeb Mon Sep 17 00:00:00 2001 From: Michael Droettboom Date: Tue, 27 Oct 2015 06:25:23 -0400 Subject: [PATCH 09/17] Fix memory management revealed by using static freetype --- src/ft2font.cpp | 4 ++++ src/ft2font_wrapper.cpp | 3 +++ 2 files changed, 7 insertions(+) diff --git a/src/ft2font.cpp b/src/ft2font.cpp index 13e843b81d93..4e05eaaa5e9f 100644 --- a/src/ft2font.cpp +++ b/src/ft2font.cpp @@ -511,6 +511,10 @@ FT2Font::FT2Font(FT_Open_Args &open_args, long hinting_factor_) : image(), face( throw "Could not set the fontsize"; } + if (open_args.stream != NULL) { + face->face_flags |= FT_FACE_FLAG_EXTERNAL_STREAM; + } + static FT_Matrix transform = { 65536 / hinting_factor, 0, 0, 65536 }; FT_Set_Transform(face, &transform, 0); } diff --git a/src/ft2font_wrapper.cpp b/src/ft2font_wrapper.cpp index e176110627df..a97de686b242 100644 --- a/src/ft2font_wrapper.cpp +++ b/src/ft2font_wrapper.cpp @@ -463,11 +463,14 @@ static PyObject *PyFT2Font_new(PyTypeObject *type, PyObject *args, PyObject *kwd PyFT2Font *self; self = (PyFT2Font *)type->tp_alloc(type, 0); self->x = NULL; + self->fname = NULL; self->py_file = NULL; self->fp = NULL; self->close_file = 0; self->offset = 0; memset(&self->stream, 0, sizeof(FT_StreamRec)); + self->mem = 0; + self->mem_size = 0; return (PyObject *)self; } From c2af9c68a6676f9d84946f56e322ba760b4dd83e Mon Sep 17 00:00:00 2001 From: Michael Droettboom Date: Tue, 27 Oct 2015 07:01:12 -0400 Subject: [PATCH 10/17] Amend, rather than override, CFLAGS --- setupext.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/setupext.py b/setupext.py index d488383e2bc1..9cc75d78a3c1 100755 --- a/setupext.py +++ b/setupext.py @@ -996,13 +996,16 @@ def do_custom_build(self): raise IOError("{0} does not match expected hash.".format(tarball)) print("Building {0}".format(tarball)) + cflags = 'CFLAGS="{0} -fPIC" '.format(os.environ.get('CFLAGS', '')) + subprocess.check_call( ['tar zxf {0}'.format(tarball)], shell=True, cwd='build') subprocess.check_call( - ['CFLAGS=-fPIC ./configure --without-zlib --without-bzip2 --without-png'], + [cflags + + './configure --without-zlib --without-bzip2 --without-png'], shell=True, cwd=src_path) subprocess.check_call( - ['CFLAGS=-fPIC make'], shell=True, cwd=src_path) + [cflags + 'make'], shell=True, cwd=src_path) class FT2Font(SetupPackage): From 5c6173a582a4cfbe0a4f3190730aaced500b74ff Mon Sep 17 00:00:00 2001 From: Michael Droettboom Date: Wed, 28 Oct 2015 09:03:40 -0400 Subject: [PATCH 11/17] freetype -> FreeType --- INSTALL | 2 +- doc/devel/testing.rst | 4 ++-- doc/glossary/index.rst | 4 ++-- doc/users/screenshots.rst | 2 +- doc/users/text_intro.rst | 2 +- examples/pylab_examples/font_table_ttf.py | 2 +- lib/matplotlib/__init__.py | 8 ++++---- lib/matplotlib/mathtext.py | 4 ++-- matplotlibrc.template | 10 +++++----- setup.cfg.template | 2 +- setupext.py | 6 +++--- src/ft2font.cpp | 4 ++-- src/ft2font.h | 4 ++-- 13 files changed, 27 insertions(+), 27 deletions(-) diff --git a/INSTALL b/INSTALL index 96dbae42b717..7a35f1df2eba 100644 --- a/INSTALL +++ b/INSTALL @@ -208,7 +208,7 @@ libpng 1.2 (or later) `pytz` Used to manipulate time-zone aware datetimes. -:term:`freetype` 2.3 or later +:term:`FreeType` 2.3 or later library for reading true type font files. ``cycler`` 0.9 or later diff --git a/doc/devel/testing.rst b/doc/devel/testing.rst index 0cc5aabcc392..b2dc7516179c 100644 --- a/doc/devel/testing.rst +++ b/doc/devel/testing.rst @@ -38,10 +38,10 @@ Build matplotlib for image comparison tests matplotlib's test suite makes heavy use of image comparison tests, meaning the result of a plot is compared against a known good result. -Unfortunately, different versions of freetype produce differently +Unfortunately, different versions of FreeType produce differently formed characters, causing these image comparisons to fail. To make them reproducible, matplotlib can be built with a special local copy -of freetype. This is recommended for all matplotlib developers. +of FreeType. This is recommended for all matplotlib developers. Add the following content to a ``setup.cfg`` file at the root of the matplotlib source directory:: diff --git a/doc/glossary/index.rst b/doc/glossary/index.rst index fe75339287d2..5f0b683f14cf 100644 --- a/doc/glossary/index.rst +++ b/doc/glossary/index.rst @@ -22,8 +22,8 @@ Glossary EPS Encapsulated Postscript (`EPS `_) - freetype - `freetype `_ is a font rasterization + FreeType + `FreeType `_ is a font rasterization library used by matplotlib which supports TrueType, Type 1, and OpenType fonts. diff --git a/doc/users/screenshots.rst b/doc/users/screenshots.rst index 57001fa763c1..a8a4be075e87 100644 --- a/doc/users/screenshots.rst +++ b/doc/users/screenshots.rst @@ -252,7 +252,7 @@ Mathtext_examples Below is a sampling of the many TeX expressions now supported by matplotlib's internal mathtext engine. The mathtext module provides TeX style mathematical -expressions using `freetype2 `_ +expressions using `FreeTYpe `_ and the BaKoMa computer modern or `STIX `_ fonts. See the :mod:`matplotlib.mathtext` module for additional details. diff --git a/doc/users/text_intro.rst b/doc/users/text_intro.rst index 4f04c9360f28..67d504dcbd5c 100644 --- a/doc/users/text_intro.rst +++ b/doc/users/text_intro.rst @@ -8,7 +8,7 @@ expressions, truetype support for raster and vector outputs, newline separated text with arbitrary rotations, and unicode support. Because we embed the fonts directly in the output documents, e.g., for postscript or PDF, what you see on the screen is what you get in the hardcopy. -`freetype2 `_ support +`FreeType `_ support produces very nice, antialiased fonts, that look good even at small raster sizes. matplotlib includes its own :mod:`matplotlib.font_manager`, thanks to Paul Barrett, which diff --git a/examples/pylab_examples/font_table_ttf.py b/examples/pylab_examples/font_table_ttf.py index 8708ae502e67..a78d39716573 100755 --- a/examples/pylab_examples/font_table_ttf.py +++ b/examples/pylab_examples/font_table_ttf.py @@ -1,6 +1,6 @@ # -*- noplot -*- """ -matplotlib has support for freetype fonts. Here's a little example +matplotlib has support for FreeType fonts. Here's a little example using the 'table' command to build a font table that shows the glyphs by character code. diff --git a/lib/matplotlib/__init__.py b/lib/matplotlib/__init__.py index 06ad93643dd5..89b635282484 100644 --- a/lib/matplotlib/__init__.py +++ b/lib/matplotlib/__init__.py @@ -1499,7 +1499,7 @@ def _init_tests(): if not os.path.isdir(os.path.join(os.path.dirname(__file__), 'tests')): raise ImportError("matplotlib test data is not installed") - # The version of freetype to install locally for running the + # The version of FreeType to install locally for running the # tests. This must match the value in `setupext.py` LOCAL_FREETYPE_VERSION = '2.5.2' @@ -1507,9 +1507,9 @@ def _init_tests(): if (ft2font.__freetype_version__ != LOCAL_FREETYPE_VERSION or ft2font.__freetype_build_type__ != 'local'): warnings.warn( - "matplotlib is not built with the correct freetype version to run " - "tests. Set local_freetype=True in setup.cfg and rebuild. Expect " - "many image comparison failures below.") + "matplotlib is not built with the correct FreeType version to run " + "tests. Set local_freetype=True in setup.cfg and rebuild. " + "Expect many image comparison failures below.") try: import nose diff --git a/lib/matplotlib/mathtext.py b/lib/matplotlib/mathtext.py index 99440a655070..e569616dc75b 100644 --- a/lib/matplotlib/mathtext.py +++ b/lib/matplotlib/mathtext.py @@ -113,7 +113,7 @@ class MathtextBackend(object): - :meth:`render_rect_filled` - :meth:`get_results` - And optionally, if you need to use a Freetype hinting style: + And optionally, if you need to use a FreeType hinting style: - :meth:`get_hinting_type` """ @@ -150,7 +150,7 @@ def get_results(self, box): def get_hinting_type(self): """ - Get the Freetype hinting type to use with this particular + Get the FreeType hinting type to use with this particular backend. """ return LOAD_NO_HINTING diff --git a/matplotlibrc.template b/matplotlibrc.template index 7492fe7b7be4..f9bb84cb4f85 100644 --- a/matplotlibrc.template +++ b/matplotlibrc.template @@ -195,10 +195,10 @@ backend : %(backend)s #text.hinting : auto # May be one of the following: # 'none': Perform no hinting - # 'auto': Use freetype's autohinter + # 'auto': Use FreeType's autohinter # 'native': Use the hinting information in the # font file, if available, and if your - # freetype library supports it + # FreeType library supports it # 'either': Use the native hinting information, # or the autohinter if none is available. # For backward compatibility, this value may also be @@ -357,9 +357,9 @@ backend : %(backend)s #image.lut : 256 # the size of the colormap lookup table #image.origin : upper # lower | upper #image.resample : False -#image.composite_image : True # When True, all the images on a set of axes are - # combined into a single composite image before - # saving a figure as a vector graphics file, +#image.composite_image : True # When True, all the images on a set of axes are + # combined into a single composite image before + # saving a figure as a vector graphics file, # such as a PDF. ### CONTOUR PLOTS diff --git a/setup.cfg.template b/setup.cfg.template index e5ea29b5163c..cae6f678e19f 100644 --- a/setup.cfg.template +++ b/setup.cfg.template @@ -11,7 +11,7 @@ [test] # If you plan to develop matplotlib and run or add to the test suite, # set this to True. It will download and build a specific version of -# freetype, and then use that to build the ft2font extension. This +# FreeType, and then use that to build the ft2font extension. This # ensures that test images are exactly reproducible. #local_freetype = False diff --git a/setupext.py b/setupext.py index 9cc75d78a3c1..5c94cfc8919d 100755 --- a/setupext.py +++ b/setupext.py @@ -20,9 +20,9 @@ PY3 = (sys.version_info[0] >= 3) -# This is the version of freetype to use when building a local version -# of freetype. It must match the value in -# lib/matplotlib.__init__.py:validate_test_dependencies +# This is the version of FreeType to use when building a local +# version. It must match the value in +# lib/matplotlib.__init__.py LOCAL_FREETYPE_VERSION = '2.5.2' # md5 hash of the freetype tarball LOCAL_FREETYPE_HASH = '004320381043d275c4e28bbacf05a1b7' diff --git a/src/ft2font.cpp b/src/ft2font.cpp index 4e05eaaa5e9f..b15a89ce1d92 100644 --- a/src/ft2font.cpp +++ b/src/ft2font.cpp @@ -25,8 +25,8 @@ transform is placed on the font to shrink it back to the desired size. While it is a bit surprising that the dpi setting affects hinting, whereas the global transform does not, this is documented - behavior of freetype, and therefore hopefully unlikely to change. - The freetype 2 tutorial says: + behavior of FreeType, and therefore hopefully unlikely to change. + The FreeType 2 tutorial says: NOTE: The transformation is applied to every glyph that is loaded through FT_Load_Glyph and is completely independent of diff --git a/src/ft2font.h b/src/ft2font.h index ee3e6e166db6..793b0e507f4a 100644 --- a/src/ft2font.h +++ b/src/ft2font.h @@ -1,6 +1,6 @@ /* -*- mode: c++; c-basic-offset: 4 -*- */ -/* A python interface to freetype2 */ +/* A python interface to FreeType */ #ifndef _FT2FONT_H #define _FT2FONT_H #include @@ -21,7 +21,7 @@ extern "C" { #define FIXED_MAJOR(val) (long)((val & 0xffff000) >> 16) #define FIXED_MINOR(val) (long)(val & 0xffff) -// the freetype string rendered into a width, height buffer +// the FreeType string rendered into a width, height buffer class FT2Image { public: From 6a9f3c47662ce8188a14bea27f82a62c2f0854f0 Mon Sep 17 00:00:00 2001 From: Michael Droettboom Date: Wed, 28 Oct 2015 09:03:51 -0400 Subject: [PATCH 12/17] Fix tense --- doc/devel/testing.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/devel/testing.rst b/doc/devel/testing.rst index b2dc7516179c..cc89a7256cba 100644 --- a/doc/devel/testing.rst +++ b/doc/devel/testing.rst @@ -33,8 +33,8 @@ Optionally you can install: - `pep8 `_ to test coding standards -Build matplotlib for image comparison tests -------------------------------------------- +Building matplotlib for image comparison tests +---------------------------------------------- matplotlib's test suite makes heavy use of image comparison tests, meaning the result of a plot is compared against a known good result. From 85a6e7800f300d3e129698f6c7e758b0ca349ae5 Mon Sep 17 00:00:00 2001 From: Michael Droettboom Date: Wed, 28 Oct 2015 09:03:57 -0400 Subject: [PATCH 13/17] Fix name of config parameter in docs --- doc/devel/testing.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/devel/testing.rst b/doc/devel/testing.rst index cc89a7256cba..3b8fb66e9872 100644 --- a/doc/devel/testing.rst +++ b/doc/devel/testing.rst @@ -47,7 +47,7 @@ Add the following content to a ``setup.cfg`` file at the root of the matplotlib source directory:: [test] - testing_freetype = True + local_freetype = True Running the tests ----------------- From 660adc6c6371ae72163e78c23e799a914429f3a5 Mon Sep 17 00:00:00 2001 From: Michael Droettboom Date: Wed, 28 Oct 2015 17:17:30 -0400 Subject: [PATCH 14/17] Make setup.py develop work --- setupext.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/setupext.py b/setupext.py index 5c94cfc8919d..dcd017339642 100755 --- a/setupext.py +++ b/setupext.py @@ -990,6 +990,8 @@ def do_custom_build(self): else: from urllib.request import urlretrieve + if not os.path.exists('build'): + os.makedirs('build') urlretrieve(tarball_url, tarball_path) if get_file_hash(tarball_path) != LOCAL_FREETYPE_HASH: From 13be4e7edf7483183e42f1745369e96a58d4fc37 Mon Sep 17 00:00:00 2001 From: Michael Droettboom Date: Wed, 28 Oct 2015 17:39:54 -0400 Subject: [PATCH 15/17] Don't use shell to call tar --- setupext.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setupext.py b/setupext.py index dcd017339642..4f4d92b54602 100755 --- a/setupext.py +++ b/setupext.py @@ -1001,7 +1001,7 @@ def do_custom_build(self): cflags = 'CFLAGS="{0} -fPIC" '.format(os.environ.get('CFLAGS', '')) subprocess.check_call( - ['tar zxf {0}'.format(tarball)], shell=True, cwd='build') + ['tar', 'zxf', tarball], cwd='build') subprocess.check_call( [cflags + './configure --without-zlib --without-bzip2 --without-png'], From 420cd8e9c64d5f9ea7086b40081b81634b13c04e Mon Sep 17 00:00:00 2001 From: Michael Droettboom Date: Thu, 29 Oct 2015 07:45:37 -0400 Subject: [PATCH 16/17] Use freetype 2.6.1 --- lib/matplotlib/__init__.py | 2 +- setupext.py | 9 ++++----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/lib/matplotlib/__init__.py b/lib/matplotlib/__init__.py index 89b635282484..c81cc8106a53 100644 --- a/lib/matplotlib/__init__.py +++ b/lib/matplotlib/__init__.py @@ -1501,7 +1501,7 @@ def _init_tests(): # The version of FreeType to install locally for running the # tests. This must match the value in `setupext.py` - LOCAL_FREETYPE_VERSION = '2.5.2' + LOCAL_FREETYPE_VERSION = '2.6.1' from matplotlib import ft2font if (ft2font.__freetype_version__ != LOCAL_FREETYPE_VERSION or diff --git a/setupext.py b/setupext.py index 4f4d92b54602..cdeb709389b1 100755 --- a/setupext.py +++ b/setupext.py @@ -23,9 +23,9 @@ # This is the version of FreeType to use when building a local # version. It must match the value in # lib/matplotlib.__init__.py -LOCAL_FREETYPE_VERSION = '2.5.2' +LOCAL_FREETYPE_VERSION = '2.6.1' # md5 hash of the freetype tarball -LOCAL_FREETYPE_HASH = '004320381043d275c4e28bbacf05a1b7' +LOCAL_FREETYPE_HASH = '348e667d728c597360e4a87c16556597' if sys.platform != 'win32': if sys.version_info[0] < 3: @@ -1003,9 +1003,8 @@ def do_custom_build(self): subprocess.check_call( ['tar', 'zxf', tarball], cwd='build') subprocess.check_call( - [cflags + - './configure --without-zlib --without-bzip2 --without-png'], - shell=True, cwd=src_path) + [cflags + './configure --with-zlib=no --with-bzip2=no ' + '--with-png=no --with-harfbuzz=no'], shell=True, cwd=src_path) subprocess.check_call( [cflags + 'make'], shell=True, cwd=src_path) From 31cb9b33a4613f6ca00de85453e0b212e3ba8b89 Mon Sep 17 00:00:00 2001 From: Michael Droettboom Date: Thu, 29 Oct 2015 12:04:10 -0400 Subject: [PATCH 17/17] Fix capitalization --- doc/users/screenshots.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/users/screenshots.rst b/doc/users/screenshots.rst index a8a4be075e87..90dafe5eba14 100644 --- a/doc/users/screenshots.rst +++ b/doc/users/screenshots.rst @@ -252,7 +252,7 @@ Mathtext_examples Below is a sampling of the many TeX expressions now supported by matplotlib's internal mathtext engine. The mathtext module provides TeX style mathematical -expressions using `FreeTYpe `_ +expressions using `FreeType `_ and the BaKoMa computer modern or `STIX `_ fonts. See the :mod:`matplotlib.mathtext` module for additional details.