summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--third_party/freetype-py/.gitignore54
-rw-r--r--third_party/freetype-py/LICENSE.txt30
-rw-r--r--third_party/freetype-py/MANIFEST.in10
-rw-r--r--third_party/freetype-py/NOTES.txt40
-rw-r--r--third_party/freetype-py/README.rst92
-rw-r--r--third_party/freetype-py/README.third_party10
-rw-r--r--third_party/freetype-py/debian/changelog5
-rw-r--r--third_party/freetype-py/debian/compat1
-rw-r--r--third_party/freetype-py/debian/control16
-rw-r--r--third_party/freetype-py/debian/copyright59
-rw-r--r--third_party/freetype-py/debian/python-freetype-py.lintian-overrides2
-rwxr-xr-xthird_party/freetype-py/debian/rules8
-rw-r--r--third_party/freetype-py/debian/source/format1
-rw-r--r--third_party/freetype-py/doc/Makefile130
-rw-r--r--third_party/freetype-py/doc/_static/G.pngbin0 -> 25511 bytes
-rw-r--r--third_party/freetype-py/doc/_static/S.pngbin0 -> 55986 bytes
-rw-r--r--third_party/freetype-py/doc/_static/agg-trick.pngbin0 -> 98432 bytes
-rw-r--r--third_party/freetype-py/doc/_static/hello-world.pngbin0 -> 8697 bytes
-rw-r--r--third_party/freetype-py/doc/_static/opengl.pngbin0 -> 80186 bytes
-rw-r--r--third_party/freetype-py/doc/_static/outline.pngbin0 -> 25701 bytes
-rw-r--r--third_party/freetype-py/doc/_static/wordle.pngbin0 -> 119705 bytes
-rw-r--r--third_party/freetype-py/doc/api.rst20
-rw-r--r--third_party/freetype-py/doc/bbox.rst6
-rw-r--r--third_party/freetype-py/doc/bitmap.rst6
-rw-r--r--third_party/freetype-py/doc/bitmap_glyph.rst6
-rw-r--r--third_party/freetype-py/doc/bitmap_size.rst6
-rw-r--r--third_party/freetype-py/doc/charmap.rst6
-rw-r--r--third_party/freetype-py/doc/conf.py224
-rw-r--r--third_party/freetype-py/doc/constants.rst31
-rw-r--r--third_party/freetype-py/doc/face.rst6
-rw-r--r--third_party/freetype-py/doc/ft_encodings.rst83
-rw-r--r--third_party/freetype-py/doc/ft_face_flags.rst111
-rw-r--r--third_party/freetype-py/doc/ft_fstypes.rst45
-rw-r--r--third_party/freetype-py/doc/ft_glyph_bbox_modes.rst25
-rw-r--r--third_party/freetype-py/doc/ft_glyph_formats.rst36
-rw-r--r--third_party/freetype-py/doc/ft_kerning_modes.rst21
-rw-r--r--third_party/freetype-py/doc/ft_lcd_filters.rst36
-rw-r--r--third_party/freetype-py/doc/ft_load_flags.rst131
-rw-r--r--third_party/freetype-py/doc/ft_load_targets.rst48
-rw-r--r--third_party/freetype-py/doc/ft_open_modes.rst31
-rw-r--r--third_party/freetype-py/doc/ft_outline_flags.rst69
-rw-r--r--third_party/freetype-py/doc/ft_pixel_modes.rst55
-rw-r--r--third_party/freetype-py/doc/ft_render_modes.rst45
-rw-r--r--third_party/freetype-py/doc/ft_stroker_borders.rst27
-rw-r--r--third_party/freetype-py/doc/ft_stroker_linecaps.rst21
-rw-r--r--third_party/freetype-py/doc/ft_stroker_linejoins.rst24
-rw-r--r--third_party/freetype-py/doc/ft_style_flags.rst16
-rw-r--r--third_party/freetype-py/doc/glyph.rst6
-rw-r--r--third_party/freetype-py/doc/glyph_slot.rst6
-rw-r--r--third_party/freetype-py/doc/index.rst26
-rw-r--r--third_party/freetype-py/doc/introduction.rst53
-rw-r--r--third_party/freetype-py/doc/license.rst29
-rw-r--r--third_party/freetype-py/doc/make.bat170
-rw-r--r--third_party/freetype-py/doc/make_enums.py48
-rw-r--r--third_party/freetype-py/doc/notes.rst44
-rw-r--r--third_party/freetype-py/doc/outline.rst6
-rw-r--r--third_party/freetype-py/doc/screenshots.rst34
-rw-r--r--third_party/freetype-py/doc/sfnt_name.rst6
-rw-r--r--third_party/freetype-py/doc/size_metrics.rst6
-rw-r--r--third_party/freetype-py/doc/stroker.rst6
-rw-r--r--third_party/freetype-py/doc/tt_adobe_ids.rst25
-rw-r--r--third_party/freetype-py/doc/tt_apple_ids.rst37
-rw-r--r--third_party/freetype-py/doc/tt_mac_ids.rst74
-rw-r--r--third_party/freetype-py/doc/tt_mac_langids.rst246
-rw-r--r--third_party/freetype-py/doc/tt_ms_ids.rst49
-rw-r--r--third_party/freetype-py/doc/tt_ms_langids.rst496
-rw-r--r--third_party/freetype-py/doc/tt_name_ids.rst50
-rw-r--r--third_party/freetype-py/doc/tt_platforms.rst47
-rw-r--r--third_party/freetype-py/doc/usage.rst12
-rw-r--r--third_party/freetype-py/examples/Vera.ttfbin0 -> 65932 bytes
-rw-r--r--third_party/freetype-py/examples/VeraMono.ttfbin0 -> 49224 bytes
-rw-r--r--third_party/freetype-py/examples/agg-trick.py73
-rw-r--r--third_party/freetype-py/examples/ascii.py121
-rw-r--r--third_party/freetype-py/examples/example_1.py89
-rw-r--r--third_party/freetype-py/examples/font-info.py42
-rw-r--r--third_party/freetype-py/examples/ftdump.py295
-rw-r--r--third_party/freetype-py/examples/glyph-alpha.py31
-rw-r--r--third_party/freetype-py/examples/glyph-color.py94
-rw-r--r--third_party/freetype-py/examples/glyph-lcd.py32
-rw-r--r--third_party/freetype-py/examples/glyph-metrics.py233
-rw-r--r--third_party/freetype-py/examples/glyph-monochrome.py43
-rw-r--r--third_party/freetype-py/examples/glyph-outline.py37
-rw-r--r--third_party/freetype-py/examples/glyph-vector-2.py98
-rw-r--r--third_party/freetype-py/examples/glyph-vector.py91
-rw-r--r--third_party/freetype-py/examples/hello-world.py54
-rw-r--r--third_party/freetype-py/examples/opengl.py122
-rw-r--r--third_party/freetype-py/examples/sfnt-names.py66
-rw-r--r--third_party/freetype-py/examples/shader.py163
-rw-r--r--third_party/freetype-py/examples/subpixel-positioning.py236
-rw-r--r--third_party/freetype-py/examples/texture_font.py421
-rw-r--r--third_party/freetype-py/examples/wordle.py137
-rw-r--r--third_party/freetype-py/freetype/__init__.py1989
-rw-r--r--third_party/freetype-py/freetype/ft_enums/__init__.py121
-rw-r--r--third_party/freetype-py/freetype/ft_enums/ft_encodings.py108
-rw-r--r--third_party/freetype-py/freetype/ft_enums/ft_face_flags.py134
-rw-r--r--third_party/freetype-py/freetype/ft_enums/ft_fstypes.py65
-rw-r--r--third_party/freetype-py/freetype/ft_enums/ft_glyph_bbox_modes.py37
-rw-r--r--third_party/freetype-py/freetype/ft_enums/ft_glyph_formats.py58
-rw-r--r--third_party/freetype-py/freetype/ft_enums/ft_kerning_modes.py31
-rw-r--r--third_party/freetype-py/freetype/ft_enums/ft_lcd_filters.py51
-rw-r--r--third_party/freetype-py/freetype/ft_enums/ft_load_flags.py154
-rw-r--r--third_party/freetype-py/freetype/ft_enums/ft_load_targets.py70
-rw-r--r--third_party/freetype-py/freetype/ft_enums/ft_open_modes.py45
-rw-r--r--third_party/freetype-py/freetype/ft_enums/ft_outline_flags.py87
-rw-r--r--third_party/freetype-py/freetype/ft_enums/ft_pixel_modes.py77
-rw-r--r--third_party/freetype-py/freetype/ft_enums/ft_render_modes.py57
-rw-r--r--third_party/freetype-py/freetype/ft_enums/ft_stroker_borders.py38
-rw-r--r--third_party/freetype-py/freetype/ft_enums/ft_stroker_linecaps.py34
-rw-r--r--third_party/freetype-py/freetype/ft_enums/ft_stroker_linejoins.py36
-rw-r--r--third_party/freetype-py/freetype/ft_enums/ft_style_flags.py28
-rw-r--r--third_party/freetype-py/freetype/ft_enums/tt_adobe_ids.py38
-rw-r--r--third_party/freetype-py/freetype/ft_enums/tt_apple_ids.py53
-rw-r--r--third_party/freetype-py/freetype/ft_enums/tt_mac_ids.py117
-rw-r--r--third_party/freetype-py/freetype/ft_enums/tt_mac_langids.py376
-rw-r--r--third_party/freetype-py/freetype/ft_enums/tt_ms_ids.py68
-rw-r--r--third_party/freetype-py/freetype/ft_enums/tt_ms_langids.py751
-rw-r--r--third_party/freetype-py/freetype/ft_enums/tt_name_ids.py93
-rw-r--r--third_party/freetype-py/freetype/ft_enums/tt_platforms.py63
-rw-r--r--third_party/freetype-py/freetype/ft_errors.py105
-rw-r--r--third_party/freetype-py/freetype/ft_structs.py944
-rw-r--r--third_party/freetype-py/freetype/ft_types.py155
-rwxr-xr-xthird_party/freetype-py/setup.py36
122 files changed, 11566 insertions, 0 deletions
diff --git a/third_party/freetype-py/.gitignore b/third_party/freetype-py/.gitignore
new file mode 100644
index 0000000..db4561e
--- /dev/null
+++ b/third_party/freetype-py/.gitignore
@@ -0,0 +1,54 @@
+# Byte-compiled / optimized / DLL files
+__pycache__/
+*.py[cod]
+
+# C extensions
+*.so
+
+# Distribution / packaging
+.Python
+env/
+build/
+develop-eggs/
+dist/
+downloads/
+eggs/
+lib/
+lib64/
+parts/
+sdist/
+var/
+*.egg-info/
+.installed.cfg
+*.egg
+
+# PyInstaller
+# Usually these files are written by a python script from a template
+# before PyInstaller builds the exe, so as to inject date/other infos into it.
+*.manifest
+*.spec
+
+# Installer logs
+pip-log.txt
+pip-delete-this-directory.txt
+
+# Unit test / coverage reports
+htmlcov/
+.tox/
+.coverage
+.cache
+nosetests.xml
+coverage.xml
+
+# Translations
+*.mo
+*.pot
+
+# Django stuff:
+*.log
+
+# Sphinx documentation
+docs/_build/
+
+# PyBuilder
+target/
diff --git a/third_party/freetype-py/LICENSE.txt b/third_party/freetype-py/LICENSE.txt
new file mode 100644
index 0000000..e3d4181
--- /dev/null
+++ b/third_party/freetype-py/LICENSE.txt
@@ -0,0 +1,30 @@
+freetype-py is licensed under the terms of the new or revised BSD license, as
+follows:
+
+Copyright (c) 2011-2014, Nicolas P. Rougier
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+Redistributions of source code must retain the above copyright notice, this
+list of conditions and the following disclaimer.
+
+Redistributions in binary form must reproduce the above copyright notice, this
+list of conditions and the following disclaimer in the documentation and/or
+other materials provided with the distribution.
+
+Neither the name of the freetype-py Development Team nor the names of its
+contributors may be used to endorse or promote products derived from this
+software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/third_party/freetype-py/MANIFEST.in b/third_party/freetype-py/MANIFEST.in
new file mode 100644
index 0000000..0c0387e
--- /dev/null
+++ b/third_party/freetype-py/MANIFEST.in
@@ -0,0 +1,10 @@
+# -----------------------------------------------------------------------------
+#
+# FreeType high-level python API - copyright 2011 Nicolas P. Rougier
+# Distributed under the terms of the new BSD license.
+#
+# -----------------------------------------------------------------------------
+recursive-include examples *
+include MANIFEST.in
+include LICENSE.txt
+include README.rst
diff --git a/third_party/freetype-py/NOTES.txt b/third_party/freetype-py/NOTES.txt
new file mode 100644
index 0000000..4fdf1b4
--- /dev/null
+++ b/third_party/freetype-py/NOTES.txt
@@ -0,0 +1,40 @@
+Release notes for 0.4.1
+=======================
+* Fixed a bug in Face.load_char
+* Added get_format and get_fstype in Face (titusz.pan)
+
+Release notes for 0.3.3
+=======================
+* Fixed a bug in get_kerning
+* Added test against freetype version for FT_ReferenceFace and FT_Get_FSType_Flags
+
+Release notes for 0.3.2
+=======================
+* Added wordle.py example
+* Added get_bbox for Outline class
+* Added get_cbox for Outline and Glyph classes
+* Added __del__ method to Face class
+* Set encoding (utf-8) to all source files and examples.
+* Added test against freetype version for FT_Library_SetLcdFilterWeights.
+
+Release notes for 0.3.1
+=======================
+* Added FT_Stroker bindings (enums, structs and methods)
+* Added ft-outline and ft-color examples
+* Fixed first/next char in Face
+* Pythonic interface has been documented
+
+Release notes for 0.3.0
+=======================
+* Added ftdump.py demo and necessary functions
+
+Release notes for 0.2.0
+=======================
+* Added sfnt functions
+* Added TT_XXX flags in ft_enums
+* New examples
+
+Release notes for 0.1.1
+=======================
+* Initial release
+* Working examples
diff --git a/third_party/freetype-py/README.rst b/third_party/freetype-py/README.rst
new file mode 100644
index 0000000..0308f3d
--- /dev/null
+++ b/third_party/freetype-py/README.rst
@@ -0,0 +1,92 @@
+FreeType high-level python API
+==============================
+
+Freetype python provides bindings for the FreeType library. Only the high-level API is bound.
+
+Documentation available at: http://freetype-py.readthedocs.org/en/latest/
+
+Installation
+============
+
+To be able to use freetype python, you need the freetype library version 2
+installed on your system.
+
+Mac users
+---------
+
+Freetype should be already installed on your system. If not, either install it
+using `homebrew <http://brew.sh>`_ or compile it and place the library binary
+file in '/usr/local/lib'.
+
+Linux users
+-----------
+
+Freetype should be already installed on your system. If not, either install
+relevant package from your package manager or compile from sources and place
+the library binary file in '/usr/local/lib'.
+
+Window users
+------------
+
+You can try to install a window binaries available from the Freetype site or
+you can compile it from sources. In such a case, make sure the resulting
+library binaries is named 'Freetype.dll' (and not something like
+Freetype245.dll) and make sure to place a copy in Windows/System32 directory.
+
+Usage example
+=============
+
+.. code:: python
+
+ import freetype
+ face = freetype.Face("Vera.ttf")
+ face.set_char_size( 48*64 )
+ face.load_char('S')
+ bitmap = face.glyph.bitmap
+ print bitmap.buffer
+
+Screenshots
+===========
+
+Screenshot below comes from the wordle.py example. No clever tricks here, just
+brute force.
+
+.. image:: doc/_static/wordle.png
+
+Screenshots below comes from the glyph-vector.py and glyph-vectopr-2.py
+examples showing how to access a glyph outline information and use it to draw
+the glyph. Rendering (with Bézier curves) is done using matplotlib.
+
+.. image:: doc/_static/S.png
+.. image:: doc/_static/G.png
+
+
+Screenshot below comes from the glyph-color.py showing how to draw and combine
+a glyph outline with the regular glyph.
+
+.. image:: doc/_static/outline.png
+
+The screenshot below comes from the hello-world.py example showing how to draw
+text in a bitmap (that has been zoomed in to show antialiasing).
+
+.. image:: doc/_static/hello-world.png
+
+
+The screenshot below comes from the agg-trick.py example showing an
+implementation of ideas from the `Texts Rasterization Exposures
+<http://agg.sourceforge.net/antigrain.com/research/font_rasterization/>`_ by
+Maxim Shemarev.
+
+.. image:: doc/_static/agg-trick.png
+
+
+Contributors
+============
+
+* Titusz Pan (bug report)
+* Ekkehard.Blanz (bug report)
+* Jānis Lībeks (bug report)
+* Frantisek Malina (typo)
+* Tillmann Karras (bug report & fix)
+* Matthew Sitton (bug report & fix)
+* Tao Gong (bug report)
diff --git a/third_party/freetype-py/README.third_party b/third_party/freetype-py/README.third_party
new file mode 100644
index 0000000..537cbbd
--- /dev/null
+++ b/third_party/freetype-py/README.third_party
@@ -0,0 +1,10 @@
+URL: https://github.com/rougier/freetype-py/archive/84085d788c8f92e5bbbcf57be7c5065b0a85be07.zip
+Version: 84085d788c8f92e5bbbcf57be7c5065b0a85be07
+License: Apache 2.0
+License File: LICENSE
+
+Description:
+FreeType python bindings.
+
+Local Modifications:
+None.
diff --git a/third_party/freetype-py/debian/changelog b/third_party/freetype-py/debian/changelog
new file mode 100644
index 0000000..1ef0112
--- /dev/null
+++ b/third_party/freetype-py/debian/changelog
@@ -0,0 +1,5 @@
+freetype-py (0.4.1-1) unstable; urgency=low
+
+ * source package automatically created by stdeb 0.8.2
+
+ -- Olivier Mehani <shtrom+debian@ssji.net> Mon, 29 Sep 2014 21:37:23 +1000
diff --git a/third_party/freetype-py/debian/compat b/third_party/freetype-py/debian/compat
new file mode 100644
index 0000000..ec63514
--- /dev/null
+++ b/third_party/freetype-py/debian/compat
@@ -0,0 +1 @@
+9
diff --git a/third_party/freetype-py/debian/control b/third_party/freetype-py/debian/control
new file mode 100644
index 0000000..88af14a
--- /dev/null
+++ b/third_party/freetype-py/debian/control
@@ -0,0 +1,16 @@
+Source: freetype-py
+Maintainer: Nicolas P. Rougier <Nicolas.Rougier@inria.fr>
+Section: python
+Priority: optional
+Build-Depends: python-all (>= 2.6.6-3), debhelper (>= 9)
+Standards-Version: 3.9.5
+
+Package: python-freetype-py
+Architecture: all
+Depends: ${misc:Depends}, ${python:Depends}, libfreetype6
+Description: Freetype python bindings
+ Freetype python provides bindings for the FreeType library. Only the
+ high-level API is bound.
+ .
+ Documentation available at:
+ http://freetype-py.readthedocs.org/en/latest/
diff --git a/third_party/freetype-py/debian/copyright b/third_party/freetype-py/debian/copyright
new file mode 100644
index 0000000..50927eb
--- /dev/null
+++ b/third_party/freetype-py/debian/copyright
@@ -0,0 +1,59 @@
+Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
+Upstream-Name: freetype-py
+Source: https://github.com/rougier/freetype-py
+
+Files: *
+Copyright: 2011-2014 Nicolas P. Rougier <nicolas.rougier@inria.fr>
+License: BSD
+ freetype-py is licensed under the terms of the new or revised BSD
+ license, as follows:
+ .
+ Copyright (c) 2011-2014, Nicolas P. Rougier All rights reserved.
+ .
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ .
+ Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ .
+ Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ .
+ Neither the name of the freetype-py Development Team nor the names
+ of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written
+ permission.
+ .
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+Files: debian/*
+Copyright: 2014 Olivier Mehani <shtrom+debian@ssji.net>
+License: GPL-2+
+ This package is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+ .
+ This package 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 <http://www.gnu.org/licenses/>
+ .
+ On Debian systems, the complete text of the GNU General
+ Public License version 2 can be found in "/usr/share/common-licenses/GPL-2".
diff --git a/third_party/freetype-py/debian/python-freetype-py.lintian-overrides b/third_party/freetype-py/debian/python-freetype-py.lintian-overrides
new file mode 100644
index 0000000..0470c16
--- /dev/null
+++ b/third_party/freetype-py/debian/python-freetype-py.lintian-overrides
@@ -0,0 +1,2 @@
+new-package-should-close-itp-bug
+invalid-short-name-in-dep5-copyright
diff --git a/third_party/freetype-py/debian/rules b/third_party/freetype-py/debian/rules
new file mode 100755
index 0000000..2ea34c0
--- /dev/null
+++ b/third_party/freetype-py/debian/rules
@@ -0,0 +1,8 @@
+#!/usr/bin/make -f
+
+# This file was automatically generated by stdeb 0.8.2 at
+# Mon, 29 Sep 2014 21:37:23 +1000
+export PYBUILD_NAME=freetype-py
+%:
+ dh $@ --with python2 --buildsystem=pybuild
+
diff --git a/third_party/freetype-py/debian/source/format b/third_party/freetype-py/debian/source/format
new file mode 100644
index 0000000..163aaf8
--- /dev/null
+++ b/third_party/freetype-py/debian/source/format
@@ -0,0 +1 @@
+3.0 (quilt)
diff --git a/third_party/freetype-py/doc/Makefile b/third_party/freetype-py/doc/Makefile
new file mode 100644
index 0000000..00f9c4e
--- /dev/null
+++ b/third_party/freetype-py/doc/Makefile
@@ -0,0 +1,130 @@
+# Makefile for Sphinx documentation
+#
+
+# You can set these variables from the command line.
+SPHINXOPTS =
+SPHINXBUILD = sphinx-build
+PAPER =
+BUILDDIR = _build
+
+# Internal variables.
+PAPEROPT_a4 = -D latex_paper_size=a4
+PAPEROPT_letter = -D latex_paper_size=letter
+ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
+
+.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest
+
+help:
+ @echo "Please use \`make <target>' where <target> is one of"
+ @echo " html to make standalone HTML files"
+ @echo " dirhtml to make HTML files named index.html in directories"
+ @echo " singlehtml to make a single large HTML file"
+ @echo " pickle to make pickle files"
+ @echo " json to make JSON files"
+ @echo " htmlhelp to make HTML files and a HTML help project"
+ @echo " qthelp to make HTML files and a qthelp project"
+ @echo " devhelp to make HTML files and a Devhelp project"
+ @echo " epub to make an epub"
+ @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
+ @echo " latexpdf to make LaTeX files and run them through pdflatex"
+ @echo " text to make text files"
+ @echo " man to make manual pages"
+ @echo " changes to make an overview of all changed/added/deprecated items"
+ @echo " linkcheck to check all external links for integrity"
+ @echo " doctest to run all doctests embedded in the documentation (if enabled)"
+
+clean:
+ -rm -rf $(BUILDDIR)/*
+
+html:
+ $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
+ @echo
+ @echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
+
+dirhtml:
+ $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
+ @echo
+ @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
+
+singlehtml:
+ $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
+ @echo
+ @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
+
+pickle:
+ $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
+ @echo
+ @echo "Build finished; now you can process the pickle files."
+
+json:
+ $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
+ @echo
+ @echo "Build finished; now you can process the JSON files."
+
+htmlhelp:
+ $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
+ @echo
+ @echo "Build finished; now you can run HTML Help Workshop with the" \
+ ".hhp project file in $(BUILDDIR)/htmlhelp."
+
+qthelp:
+ $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
+ @echo
+ @echo "Build finished; now you can run "qcollectiongenerator" with the" \
+ ".qhcp project file in $(BUILDDIR)/qthelp, like this:"
+ @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/FreetypePython.qhcp"
+ @echo "To view the help file:"
+ @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/FreetypePython.qhc"
+
+devhelp:
+ $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
+ @echo
+ @echo "Build finished."
+ @echo "To view the help file:"
+ @echo "# mkdir -p $$HOME/.local/share/devhelp/FreetypePython"
+ @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/FreetypePython"
+ @echo "# devhelp"
+
+epub:
+ $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
+ @echo
+ @echo "Build finished. The epub file is in $(BUILDDIR)/epub."
+
+latex:
+ $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+ @echo
+ @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
+ @echo "Run \`make' in that directory to run these through (pdf)latex" \
+ "(use \`make latexpdf' here to do that automatically)."
+
+latexpdf:
+ $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+ @echo "Running LaTeX files through pdflatex..."
+ make -C $(BUILDDIR)/latex all-pdf
+ @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
+
+text:
+ $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
+ @echo
+ @echo "Build finished. The text files are in $(BUILDDIR)/text."
+
+man:
+ $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
+ @echo
+ @echo "Build finished. The manual pages are in $(BUILDDIR)/man."
+
+changes:
+ $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
+ @echo
+ @echo "The overview file is in $(BUILDDIR)/changes."
+
+linkcheck:
+ $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
+ @echo
+ @echo "Link check complete; look for any errors in the above output " \
+ "or in $(BUILDDIR)/linkcheck/output.txt."
+
+doctest:
+ $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
+ @echo "Testing of doctests in the sources finished, look at the " \
+ "results in $(BUILDDIR)/doctest/output.txt."
diff --git a/third_party/freetype-py/doc/_static/G.png b/third_party/freetype-py/doc/_static/G.png
new file mode 100644
index 0000000..80aaa3d
--- /dev/null
+++ b/third_party/freetype-py/doc/_static/G.png
Binary files differ
diff --git a/third_party/freetype-py/doc/_static/S.png b/third_party/freetype-py/doc/_static/S.png
new file mode 100644
index 0000000..81ea28d
--- /dev/null
+++ b/third_party/freetype-py/doc/_static/S.png
Binary files differ
diff --git a/third_party/freetype-py/doc/_static/agg-trick.png b/third_party/freetype-py/doc/_static/agg-trick.png
new file mode 100644
index 0000000..aa29b33
--- /dev/null
+++ b/third_party/freetype-py/doc/_static/agg-trick.png
Binary files differ
diff --git a/third_party/freetype-py/doc/_static/hello-world.png b/third_party/freetype-py/doc/_static/hello-world.png
new file mode 100644
index 0000000..f62d282
--- /dev/null
+++ b/third_party/freetype-py/doc/_static/hello-world.png
Binary files differ
diff --git a/third_party/freetype-py/doc/_static/opengl.png b/third_party/freetype-py/doc/_static/opengl.png
new file mode 100644
index 0000000..816d4da
--- /dev/null
+++ b/third_party/freetype-py/doc/_static/opengl.png
Binary files differ
diff --git a/third_party/freetype-py/doc/_static/outline.png b/third_party/freetype-py/doc/_static/outline.png
new file mode 100644
index 0000000..1ed76a1
--- /dev/null
+++ b/third_party/freetype-py/doc/_static/outline.png
Binary files differ
diff --git a/third_party/freetype-py/doc/_static/wordle.png b/third_party/freetype-py/doc/_static/wordle.png
new file mode 100644
index 0000000..216a076
--- /dev/null
+++ b/third_party/freetype-py/doc/_static/wordle.png
Binary files differ
diff --git a/third_party/freetype-py/doc/api.rst b/third_party/freetype-py/doc/api.rst
new file mode 100644
index 0000000..74588eb
--- /dev/null
+++ b/third_party/freetype-py/doc/api.rst
@@ -0,0 +1,20 @@
+===
+API
+===
+
+.. toctree::
+ :maxdepth: 2
+
+ face.rst
+ bbox.rst
+ size_metrics.rst
+ bitmap_size.rst
+ bitmap.rst
+ charmap.rst
+ outline.rst
+ glyph.rst
+ bitmap_glyph.rst
+ glyph_slot.rst
+ sfnt_name.rst
+ stroker.rst
+ constants.rst
diff --git a/third_party/freetype-py/doc/bbox.rst b/third_party/freetype-py/doc/bbox.rst
new file mode 100644
index 0000000..89ce86c
--- /dev/null
+++ b/third_party/freetype-py/doc/bbox.rst
@@ -0,0 +1,6 @@
+.. currentmodule:: freetype
+
+BBox
+====
+.. autoclass:: BBox
+ :members:
diff --git a/third_party/freetype-py/doc/bitmap.rst b/third_party/freetype-py/doc/bitmap.rst
new file mode 100644
index 0000000..c6ef17e
--- /dev/null
+++ b/third_party/freetype-py/doc/bitmap.rst
@@ -0,0 +1,6 @@
+.. currentmodule:: freetype
+
+Bitmap
+======
+.. autoclass:: Bitmap
+ :members:
diff --git a/third_party/freetype-py/doc/bitmap_glyph.rst b/third_party/freetype-py/doc/bitmap_glyph.rst
new file mode 100644
index 0000000..e73e642
--- /dev/null
+++ b/third_party/freetype-py/doc/bitmap_glyph.rst
@@ -0,0 +1,6 @@
+.. currentmodule:: freetype
+
+Bitmap glyph
+============
+.. autoclass:: BitmapGlyph
+ :members:
diff --git a/third_party/freetype-py/doc/bitmap_size.rst b/third_party/freetype-py/doc/bitmap_size.rst
new file mode 100644
index 0000000..f4f1793
--- /dev/null
+++ b/third_party/freetype-py/doc/bitmap_size.rst
@@ -0,0 +1,6 @@
+.. currentmodule:: freetype
+
+Bitmap size
+===========
+.. autoclass:: BitmapSize
+ :members:
diff --git a/third_party/freetype-py/doc/charmap.rst b/third_party/freetype-py/doc/charmap.rst
new file mode 100644
index 0000000..0e61c0f
--- /dev/null
+++ b/third_party/freetype-py/doc/charmap.rst
@@ -0,0 +1,6 @@
+.. currentmodule:: freetype
+
+Charmap
+=======
+.. autoclass:: Charmap
+ :members:
diff --git a/third_party/freetype-py/doc/conf.py b/third_party/freetype-py/doc/conf.py
new file mode 100644
index 0000000..ca1888b
--- /dev/null
+++ b/third_party/freetype-py/doc/conf.py
@@ -0,0 +1,224 @@
+# -*- coding: utf-8 -*-
+#
+# Freetype/Python documentation build configuration file, created by
+# sphinx-quickstart on Wed Nov 9 16:29:54 2011.
+#
+# This file is execfile()d with the current directory set to its containing dir.
+#
+# Note that not all possible configuration values are present in this
+# autogenerated file.
+#
+# All configuration values have a default; values that are commented out
+# serve to show the default.
+
+import sys, os
+
+# If extensions (or modules to document with autodoc) are in another directory,
+# add these directories to sys.path here. If the directory is relative to the
+# documentation root, use os.path.abspath to make it absolute, like shown here.
+#sys.path.insert(0, os.path.abspath('.'))
+
+# -- General configuration -----------------------------------------------------
+
+# If your documentation needs a minimal Sphinx version, state it here.
+#needs_sphinx = '1.0'
+
+# Add any Sphinx extension module names here, as strings. They can be extensions
+# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
+extensions = ['sphinx.ext.autodoc']
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ['_templates']
+
+# The suffix of source filenames.
+source_suffix = '.rst'
+
+# The encoding of source files.
+#source_encoding = 'utf-8-sig'
+
+# The master toctree document.
+master_doc = 'index'
+
+# General information about the project.
+project = u'Freetype python bindings'
+copyright = u'2011-2014, Nicolas P. Rougier'
+
+# The version info for the project you're documenting, acts as replacement for
+# |version| and |release|, also used in various other places throughout the
+# built documents.
+#
+# The short X.Y version.
+version = '0.4.1'
+# The full version, including alpha/beta/rc tags.
+release = '0.4.1'
+
+# The language for content autogenerated by Sphinx. Refer to documentation
+# for a list of supported languages.
+#language = None
+
+# There are two options for replacing |today|: either, you set today to some
+# non-false value, then it is used:
+#today = ''
+# Else, today_fmt is used as the format for a strftime call.
+#today_fmt = '%B %d, %Y'
+
+# List of patterns, relative to source directory, that match files and
+# directories to ignore when looking for source files.
+exclude_patterns = ['_build']
+
+# The reST default role (used for this markup: `text`) to use for all documents.
+#default_role = None
+
+# If true, '()' will be appended to :func: etc. cross-reference text.
+#add_function_parentheses = True
+
+# If true, the current module name will be prepended to all description
+# unit titles (such as .. function::).
+#add_module_names = True
+
+# If true, sectionauthor and moduleauthor directives will be shown in the
+# output. They are ignored by default.
+#show_authors = False
+
+# The name of the Pygments (syntax highlighting) style to use.
+pygments_style = 'sphinx'
+
+# A list of ignored prefixes for module index sorting.
+#modindex_common_prefix = []
+
+
+# -- Options for HTML output ---------------------------------------------------
+
+# The theme to use for HTML and HTML Help pages. See the documentation for
+# a list of builtin themes.
+# html_theme = 'default'
+
+# Theme options are theme-specific and customize the look and feel of a theme
+# further. For a list of options available for each theme, see the
+# documentation.
+#html_theme_options = {}
+
+# on_rtd is whether we are on readthedocs.org, this line of code grabbed from docs.readthedocs.org
+on_rtd = os.environ.get('READTHEDOCS', None) == 'True'
+# only import and set the theme if we're building docs locally
+if not on_rtd:
+ import sphinx_rtd_theme
+ html_theme = 'sphinx_rtd_theme'
+ html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]
+
+# Add any paths that contain custom themes here, relative to this directory.
+#html_theme_path = []
+
+# The name for this set of Sphinx documents. If None, it defaults to
+# "<project> v<release> documentation".
+#html_title = None
+
+# A shorter title for the navigation bar. Default is the same as html_title.
+#html_short_title = None
+
+# The name of an image file (relative to this directory) to place at the top
+# of the sidebar.
+#html_logo = None
+
+# The name of an image file (within the static path) to use as favicon of the
+# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
+# pixels large.
+#html_favicon = None
+
+# Add any paths that contain custom static files (such as style sheets) here,
+# relative to this directory. They are copied after the builtin static files,
+# so a file named "default.css" will overwrite the builtin "default.css".
+html_static_path = ['_static']
+
+# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
+# using the given strftime format.
+#html_last_updated_fmt = '%b %d, %Y'
+
+# If true, SmartyPants will be used to convert quotes and dashes to
+# typographically correct entities.
+#html_use_smartypants = True
+
+# Custom sidebar templates, maps document names to template names.
+#html_sidebars = {}
+
+# Additional templates that should be rendered to pages, maps page names to
+# template names.
+#html_additional_pages = {}
+
+# If false, no module index is generated.
+#html_domain_indices = True
+
+# If false, no index is generated.
+#html_use_index = True
+
+# If true, the index is split into individual pages for each letter.
+#html_split_index = False
+
+# If true, links to the reST sources are added to the pages.
+#html_show_sourcelink = True
+
+# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
+#html_show_sphinx = True
+
+# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
+#html_show_copyright = True
+
+# If true, an OpenSearch description file will be output, and all pages will
+# contain a <link> tag referring to it. The value of this option must be the
+# base URL from which the finished HTML is served.
+#html_use_opensearch = ''
+
+# This is the file name suffix for HTML files (e.g. ".xhtml").
+#html_file_suffix = None
+
+# Output file base name for HTML help builder.
+htmlhelp_basename = 'FreetypePythondoc'
+
+
+# -- Options for LaTeX output --------------------------------------------------
+
+# The paper size ('letter' or 'a4').
+#latex_paper_size = 'letter'
+
+# The font size ('10pt', '11pt' or '12pt').
+#latex_font_size = '10pt'
+
+# Grouping the document tree into LaTeX files. List of tuples
+# (source start file, target name, title, author, documentclass [howto/manual]).
+latex_documents = [
+ ('index', 'FreetypePython.tex', u'Freetype Python Documentation',
+ u'Nicolas P. Rougier', 'manual'),
+]
+
+# The name of an image file (relative to this directory) to place at the top of
+# the title page.
+#latex_logo = None
+
+# For "manual" documents, if this is true, then toplevel headings are parts,
+# not chapters.
+#latex_use_parts = False
+
+# If true, show page references after internal links.
+#latex_show_pagerefs = False
+
+# If true, show URL addresses after external links.
+#latex_show_urls = False
+
+# Additional stuff for the LaTeX preamble.
+#latex_preamble = ''
+
+# Documents to append as an appendix to all manuals.
+#latex_appendices = []
+
+# If false, no module index is generated.
+#latex_domain_indices = True
+
+
+# -- Options for manual page output --------------------------------------------
+
+# One entry per manual page. List of tuples
+# (source start file, name, description, authors, manual section).
+man_pages = [
+ ('index', 'freetypepython', u'Freetype Python Documentation',
+ [u'Nicolas P. Rougier'], 1)
+]
diff --git a/third_party/freetype-py/doc/constants.rst b/third_party/freetype-py/doc/constants.rst
new file mode 100644
index 0000000..e36327a
--- /dev/null
+++ b/third_party/freetype-py/doc/constants.rst
@@ -0,0 +1,31 @@
+Constants
+=========
+
+.. toctree::
+ :maxdepth: 1
+
+ ft_encodings.rst
+ ft_face_flags.rst
+ ft_fstypes.rst
+ ft_glyph_bbox_modes.rst
+ ft_glyph_formats.rst
+ ft_kerning_modes.rst
+ ft_lcd_filters.rst
+ ft_load_flags.rst
+ ft_load_targets.rst
+ ft_open_modes.rst
+ ft_outline_flags.rst
+ ft_pixel_modes.rst
+ ft_render_modes.rst
+ ft_stroker_borders.rst
+ ft_stroker_linecaps.rst
+ ft_stroker_linejoins.rst
+ ft_style_flags.rst
+ tt_adobe_ids.rst
+ tt_apple_ids.rst
+ tt_mac_ids.rst
+ tt_mac_langids.rst
+ tt_ms_ids.rst
+ tt_ms_langids.rst
+ tt_name_ids.rst
+ tt_platforms.rst
diff --git a/third_party/freetype-py/doc/face.rst b/third_party/freetype-py/doc/face.rst
new file mode 100644
index 0000000..625db5a
--- /dev/null
+++ b/third_party/freetype-py/doc/face.rst
@@ -0,0 +1,6 @@
+.. currentmodule:: freetype
+
+Face
+====
+.. autoclass:: Face
+ :members:
diff --git a/third_party/freetype-py/doc/ft_encodings.rst b/third_party/freetype-py/doc/ft_encodings.rst
new file mode 100644
index 0000000..fc53e30
--- /dev/null
+++ b/third_party/freetype-py/doc/ft_encodings.rst
@@ -0,0 +1,83 @@
+FT_ENCODINGS
+============
+
+An enumeration used to specify character sets supported by charmaps. Used in
+the FT_Select_Charmap API function.
+
+.. data:: FT_ENCODING_NONE
+
+ The encoding value 0 is reserved.
+
+.. data:: FT_ENCODING_UNICODE
+
+ Corresponds to the Unicode character set. This value covers all versions of
+ the Unicode repertoire, including ASCII and Latin-1. Most fonts include a
+ Unicode charmap, but not all of them.
+
+ For example, if you want to access Unicode value U+1F028 (and the font
+ contains it), use value 0x1F028 as the input value for FT_Get_Char_Index.
+
+.. data:: FT_ENCODING_MS_SYMBOL
+
+ Corresponds to the Microsoft Symbol encoding, used to encode mathematical
+ symbols in the 32..255 character code range. For more information, see
+ 'http://www.ceviz.net/symbol.htm'.
+
+.. data:: FT_ENCODING_SJIS
+
+ Corresponds to Japanese SJIS encoding. More info at at
+ 'http://langsupport.japanreference.com/encoding.shtml'. See note on
+ multi-byte encodings below.
+
+.. data:: FT_ENCODING_GB2312
+
+ Corresponds to an encoding system for Simplified Chinese as used used in
+ mainland China.
+
+.. data:: FT_ENCODING_BIG5
+
+ Corresponds to an encoding system for Traditional Chinese as used in Taiwan
+ and Hong Kong.
+
+.. data:: FT_ENCODING_WANSUNG
+
+ Corresponds to the Korean encoding system known as Wansung. For more
+ information see 'http://www.microsoft.com/typography/unicode/949.txt'.
+
+.. data:: FT_ENCODING_JOHAB
+
+ The Korean standard character set (KS C 5601-1992), which corresponds to MS
+ Windows code page 1361. This character set includes all possible Hangeul
+ character combinations.
+
+.. data:: FT_ENCODING_ADOBE_LATIN_1
+
+ Corresponds to a Latin-1 encoding as defined in a Type 1 PostScript font. It
+ is limited to 256 character codes.
+
+.. data:: FT_ENCODING_ADOBE_STANDARD
+
+ Corresponds to the Adobe Standard encoding, as found in Type 1, CFF, and
+ OpenType/CFF fonts. It is limited to 256 character codes.
+
+.. data:: FT_ENCODING_ADOBE_EXPERT
+
+ Corresponds to the Adobe Expert encoding, as found in Type 1, CFF, and
+ OpenType/CFF fonts. It is limited to 256 character codes.
+
+.. data:: FT_ENCODING_ADOBE_CUSTOM
+
+ Corresponds to a custom encoding, as found in Type 1, CFF, and OpenType/CFF
+ fonts. It is limited to 256 character codes.
+
+.. data:: FT_ENCODING_APPLE_ROMAN
+
+ Corresponds to the 8-bit Apple roman encoding. Many TrueType and OpenType
+ fonts contain a charmap for this encoding, since older versions of Mac OS are
+ able to use it.
+
+.. data:: FT_ENCODING_OLD_LATIN_2
+
+ This value is deprecated and was never used nor reported by FreeType. Don't
+ use or test for it.
+
diff --git a/third_party/freetype-py/doc/ft_face_flags.rst b/third_party/freetype-py/doc/ft_face_flags.rst
new file mode 100644
index 0000000..ac303d8
--- /dev/null
+++ b/third_party/freetype-py/doc/ft_face_flags.rst
@@ -0,0 +1,111 @@
+FT_FACE_FLAGS
+=============
+
+A list of bit flags used in the 'face_flags' field of the FT_FaceRec
+structure. They inform client applications of properties of the corresponding
+face.
+
+
+.. data:: FT_FACE_FLAG_SCALABLE
+
+ Indicates that the face contains outline glyphs. This doesn't prevent bitmap
+ strikes, i.e., a face can have both this and and FT_FACE_FLAG_FIXED_SIZES
+ set.
+
+
+.. data:: FT_FACE_FLAG_FIXED_SIZES
+
+ Indicates that the face contains bitmap strikes. See also the
+ 'num_fixed_sizes' and 'available_sizes' fields of FT_FaceRec.
+
+
+.. data:: FT_FACE_FLAG_FIXED_WIDTH
+
+ Indicates that the face contains fixed-width characters (like Courier,
+ Lucido, MonoType, etc.).
+
+
+.. data:: FT_FACE_FLAG_SFNT
+
+ Indicates that the face uses the 'sfnt' storage scheme. For now, this means
+ TrueType and OpenType.
+
+
+.. data:: FT_FACE_FLAG_HORIZONTAL
+
+ Indicates that the face contains horizontal glyph metrics. This should be set
+ for all common formats.
+
+
+.. data:: FT_FACE_FLAG_VERTICAL
+
+ Indicates that the face contains vertical glyph metrics. This is only
+ available in some formats, not all of them.
+
+
+.. data:: FT_FACE_FLAG_KERNING
+
+ Indicates that the face contains kerning information. If set, the kerning
+ distance can be retrieved through the function FT_Get_Kerning. Otherwise the
+ function always return the vector (0,0). Note that FreeType doesn't handle
+ kerning data from the 'GPOS' table (as present in some OpenType fonts).
+
+
+.. data:: FT_FACE_FLAG_MULTIPLE_MASTERS
+
+ Indicates that the font contains multiple masters and is capable of
+ interpolating between them. See the multiple-masters specific API for
+ details.
+
+
+.. data:: FT_FACE_FLAG_GLYPH_NAMES
+
+ Indicates that the font contains glyph names that can be retrieved through
+ FT_Get_Glyph_Name. Note that some TrueType fonts contain broken glyph name
+ tables. Use the function FT_Has_PS_Glyph_Names when needed.
+
+
+.. data:: FT_FACE_FLAG_EXTERNAL_STREAM
+
+ Used internally by FreeType to indicate that a face's stream was provided by
+ the client application and should not be destroyed when FT_Done_Face is
+ called. Don't read or test this flag.
+
+
+.. data:: FT_FACE_FLAG_HINTER
+
+ Set if the font driver has a hinting machine of its own. For example, with
+ TrueType fonts, it makes sense to use data from the SFNT 'gasp' table only if
+ the native TrueType hinting engine (with the bytecode interpreter) is
+ available and active.
+
+
+.. data:: FT_FACE_FLAG_CID_KEYED
+
+ Set if the font is CID-keyed. In that case, the font is not accessed by glyph
+ indices but by CID values. For subsetted CID-keyed fonts this has the
+ consequence that not all index values are a valid argument to
+ FT_Load_Glyph. Only the CID values for which corresponding glyphs in the
+ subsetted font exist make FT_Load_Glyph return successfully; in all other
+ cases you get an 'FT_Err_Invalid_Argument' error.
+
+ Note that CID-keyed fonts which are in an SFNT wrapper don't have this flag
+ set since the glyphs are accessed in the normal way (using contiguous
+ indices); the 'CID-ness' isn't visible to the application.
+
+
+.. data:: FT_FACE_FLAG_TRICKY
+
+ Set if the font is 'tricky', this is, it always needs the font format's
+ native hinting engine to get a reasonable result. A typical example is the
+ Chinese font 'mingli.ttf' which uses TrueType bytecode instructions to move
+ and scale all of its subglyphs.
+
+ It is not possible to autohint such fonts using FT_LOAD_FORCE_AUTOHINT; it
+ will also ignore FT_LOAD_NO_HINTING. You have to set both FT_LOAD_NO_HINTING
+ and FT_LOAD_NO_AUTOHINT to really disable hinting; however, you probably
+ never want this except for demonstration purposes.
+
+ Currently, there are six TrueType fonts in the list of tricky fonts; they are
+ hard-coded in file 'ttobjs.c'.
+
diff --git a/third_party/freetype-py/doc/ft_fstypes.rst b/third_party/freetype-py/doc/ft_fstypes.rst
new file mode 100644
index 0000000..e6b1cab
--- /dev/null
+++ b/third_party/freetype-py/doc/ft_fstypes.rst
@@ -0,0 +1,45 @@
+FT_FSTYPES
+==========
+
+A list of bit flags that inform client applications of embedding and
+subsetting restrictions associated with a font.
+
+.. data:: FT_FSTYPE_INSTALLABLE_EMBEDDING
+
+ Fonts with no fsType bit set may be embedded and permanently installed on
+ the remote system by an application.
+
+
+.. data:: FT_FSTYPE_RESTRICTED_LICENSE_EMBEDDING
+
+ Fonts that have only this bit set must not be modified, embedded or exchanged
+ in any manner without first obtaining permission of the font software
+ copyright owner.
+
+
+.. data:: FT_FSTYPE_PREVIEW_AND_PRINT_EMBEDDING
+
+ If this bit is set, the font may be embedded and temporarily loaded on the
+ remote system. Documents containing Preview & Print fonts must be opened
+ 'read-only'; no edits can be applied to the document.
+
+
+.. data:: FT_FSTYPE_EDITABLE_EMBEDDING
+
+ If this bit is set, the font may be embedded but must only be installed
+ temporarily on other systems. In contrast to Preview & Print fonts,
+ documents containing editable fonts may be opened for reading, editing is
+ permitted, and changes may be saved.
+
+
+.. data:: FT_FSTYPE_NO_SUBSETTING
+
+ If this bit is set, the font may not be subsetted prior to embedding.
+
+
+.. data:: FT_FSTYPE_BITMAP_EMBEDDING_ONLY
+
+ If this bit is set, only bitmaps contained in the font may be embedded; no
+ outline data may be embedded. If there are no bitmaps available in the font,
+ then the font is unembeddable.
+
diff --git a/third_party/freetype-py/doc/ft_glyph_bbox_modes.rst b/third_party/freetype-py/doc/ft_glyph_bbox_modes.rst
new file mode 100644
index 0000000..f192aa3
--- /dev/null
+++ b/third_party/freetype-py/doc/ft_glyph_bbox_modes.rst
@@ -0,0 +1,25 @@
+FT_GLYPH_BBOX_MODES
+===================
+
+The mode how the values of FT_Glyph_Get_CBox are returned.
+
+.. data:: FT_GLYPH_BBOX_UNSCALED
+
+ Return unscaled font units.
+
+.. data:: FT_GLYPH_BBOX_SUBPIXELS
+
+ Return unfitted 26.6 coordinates.
+
+.. data:: FT_GLYPH_BBOX_GRIDFIT
+
+ Return grid-fitted 26.6 coordinates.
+
+.. data:: FT_GLYPH_BBOX_TRUNCATE
+
+ Return coordinates in integer pixels.
+
+.. data:: FT_GLYPH_BBOX_PIXELS
+
+ Return grid-fitted pixel coordinates.
+
diff --git a/third_party/freetype-py/doc/ft_glyph_formats.rst b/third_party/freetype-py/doc/ft_glyph_formats.rst
new file mode 100644
index 0000000..e686980
--- /dev/null
+++ b/third_party/freetype-py/doc/ft_glyph_formats.rst
@@ -0,0 +1,36 @@
+FT_GLYPH_FORMATS
+================
+
+An enumeration type used to describe the format of a given glyph image. Note
+that this version of FreeType only supports two image formats, even though
+future font drivers will be able to register their own format.
+
+.. data:: FT_GLYPH_FORMAT_NONE
+
+ The value 0 is reserved.
+
+.. data:: FT_GLYPH_FORMAT_COMPOSITE
+
+ The glyph image is a composite of several other images. This format is only
+ used with FT_LOAD_NO_RECURSE, and is used to report compound glyphs (like
+ accented characters).
+
+.. data:: FT_GLYPH_FORMAT_BITMAP
+
+ The glyph image is a bitmap, and can be described as an FT_Bitmap. You
+ generally need to access the 'bitmap' field of the FT_GlyphSlotRec structure
+ to read it.
+
+.. data:: FT_GLYPH_FORMAT_OUTLINE
+
+ The glyph image is a vectorial outline made of line segments and Bezier arcs;
+ it can be described as an FT_Outline; you generally want to access the
+ 'outline' field of the FT_GlyphSlotRec structure to read it.
+
+.. data:: FT_GLYPH_FORMAT_PLOTTER
+
+ The glyph image is a vectorial path with no inside and outside contours. Some
+ Type 1 fonts, like those in the Hershey family, contain glyphs in this
+ format. These are described as FT_Outline, but FreeType isn't currently
+ capable of rendering them correctly.
+
diff --git a/third_party/freetype-py/doc/ft_kerning_modes.rst b/third_party/freetype-py/doc/ft_kerning_modes.rst
new file mode 100644
index 0000000..1dd2198
--- /dev/null
+++ b/third_party/freetype-py/doc/ft_kerning_modes.rst
@@ -0,0 +1,21 @@
+FT_KERNING_MODES
+================
+
+An enumeration used to specify which kerning values to return in
+.. data:: FT_Get_Kerning.
+
+
+.. data:: FT_KERNING_DEFAULT
+
+ Return scaled and grid-fitted kerning distances (value is 0).
+
+
+.. data:: FT_KERNING_UNFITTED
+
+ Return scaled but un-grid-fitted kerning distances.
+
+
+.. data:: FT_KERNING_UNSCALED
+
+ Return the kerning vector in original font units.
+
diff --git a/third_party/freetype-py/doc/ft_lcd_filters.rst b/third_party/freetype-py/doc/ft_lcd_filters.rst
new file mode 100644
index 0000000..4e407e0
--- /dev/null
+++ b/third_party/freetype-py/doc/ft_lcd_filters.rst
@@ -0,0 +1,36 @@
+FT_LCD_FILTERS
+==============
+
+A list of values to identify various types of LCD filters.
+
+
+.. data:: FT_LCD_FILTER_NONE
+
+ Do not perform filtering. When used with subpixel rendering, this results in
+ sometimes severe color fringes.
+
+
+.. data:: FT_LCD_FILTER_DEFAULT
+
+ The default filter reduces color fringes considerably, at the cost of a
+ slight blurriness in the output.
+
+
+.. data:: FT_LCD_FILTER_LIGHT
+
+ The light filter is a variant that produces less blurriness at the cost of
+ slightly more color fringes than the default one. It might be better,
+ depending on taste, your monitor, or your personal vision.
+
+
+.. data:: FT_LCD_FILTER_LEGACY
+
+ This filter corresponds to the original libXft color filter. It provides high
+ contrast output but can exhibit really bad color fringes if glyphs are not
+ extremely well hinted to the pixel grid. In other words, it only works well
+ if the TrueType bytecode interpreter is enabled and high-quality hinted fonts
+ are used.
+
+ This filter is only provided for comparison purposes, and might be disabled
+ or stay unsupported in the future.
+
diff --git a/third_party/freetype-py/doc/ft_load_flags.rst b/third_party/freetype-py/doc/ft_load_flags.rst
new file mode 100644
index 0000000..5077ae5
--- /dev/null
+++ b/third_party/freetype-py/doc/ft_load_flags.rst
@@ -0,0 +1,131 @@
+FT_LOAD_FLAGS
+=============
+
+A list of bit-field constants used with FT_Load_Glyph to indicate what kind
+of operations to perform during glyph loading.
+
+
+.. data:: FT_LOAD_DEFAULT
+
+ Corresponding to 0, this value is used as the default glyph load
+ operation. In this case, the following happens:
+
+ 1. FreeType looks for a bitmap for the glyph corresponding to the face's
+ current size. If one is found, the function returns. The bitmap data can
+ be accessed from the glyph slot (see note below).
+
+ 2. If no embedded bitmap is searched or found, FreeType looks for a scalable
+ outline. If one is found, it is loaded from the font file, scaled to
+ device pixels, then 'hinted' to the pixel grid in order to optimize
+ it. The outline data can be accessed from the glyph slot (see note below).
+
+ Note that by default, the glyph loader doesn't render outlines into
+ bitmaps. The following flags are used to modify this default behaviour to
+ more specific and useful cases.
+
+
+.. data:: FT_LOAD_NO_SCALE
+
+ Don't scale the outline glyph loaded, but keep it in font units.
+
+ This flag implies FT_LOAD_NO_HINTING and FT_LOAD_NO_BITMAP, and unsets
+ FT_LOAD_RENDER.
+
+
+.. data:: FT_LOAD_NO_HINTING
+
+ Disable hinting. This generally generates 'blurrier' bitmap glyph when the
+ glyph is rendered in any of the anti-aliased modes. See also the note below.
+
+ This flag is implied by FT_LOAD_NO_SCALE.
+
+
+.. data:: FT_LOAD_RENDER
+
+ Call FT_Render_Glyph after the glyph is loaded. By default, the glyph is
+ rendered in FT_RENDER_MODE_NORMAL mode. This can be overridden by
+ FT_LOAD_TARGET_XXX or FT_LOAD_MONOCHROME.
+
+ This flag is unset by FT_LOAD_NO_SCALE.
+
+
+.. data:: FT_LOAD_NO_BITMAP
+
+ Ignore bitmap strikes when loading. Bitmap-only fonts ignore this flag.
+
+ FT_LOAD_NO_SCALE always sets this flag.
+
+
+.. data:: FT_LOAD_VERTICAL_LAYOUT
+
+ Load the glyph for vertical text layout. Don't use it as it is problematic
+ currently.
+
+
+.. data:: FT_LOAD_FORCE_AUTOHINT
+
+ Indicates that the auto-hinter is preferred over the font's native
+ hinter. See also the note below.
+
+
+.. data:: FT_LOAD_CROP_BITMAP
+
+ Indicates that the font driver should crop the loaded bitmap glyph (i.e.,
+ remove all space around its black bits). Not all drivers implement this.
+
+
+.. data:: FT_LOAD_PEDANTIC
+
+ Indicates that the font driver should perform pedantic verifications during
+ glyph loading. This is mostly used to detect broken glyphs in fonts. By
+ default, FreeType tries to handle broken fonts also.
+
+
+.. data:: FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH
+
+ Indicates that the font driver should ignore the global advance width defined
+ in the font. By default, that value is used as the advance width for all
+ glyphs when the face has FT_FACE_FLAG_FIXED_WIDTH set.
+
+ This flag exists for historical reasons (to support buggy CJK fonts).
+
+
+.. data:: FT_LOAD_NO_RECURSE
+
+ This flag is only used internally. It merely indicates that the font driver
+ should not load composite glyphs recursively. Instead, it should set the
+ 'num_subglyph' and 'subglyphs' values of the glyph slot accordingly, and set
+ 'glyph->format' to FT_GLYPH_FORMAT_COMPOSITE.
+
+ The description of sub-glyphs is not available to client applications for now.
+
+ This flag implies FT_LOAD_NO_SCALE and FT_LOAD_IGNORE_TRANSFORM.
+
+
+.. data:: FT_LOAD_IGNORE_TRANSFORM
+
+ Indicates that the transform matrix set by FT_Set_Transform should be ignored.
+
+
+.. data:: FT_LOAD_MONOCHROME
+
+ This flag is used with FT_LOAD_RENDER to indicate that you want to render an
+ outline glyph to a 1-bit monochrome bitmap glyph, with 8 pixels packed into
+ each byte of the bitmap data.
+
+ Note that this has no effect on the hinting algorithm used. You should rather
+ use FT_LOAD_TARGET_MONO so that the monochrome-optimized hinting algorithm is
+ used.
+
+
+.. data:: FT_LOAD_LINEAR_DESIGN
+
+ Indicates that the 'linearHoriAdvance' and 'linearVertAdvance' fields of
+ FT_GlyphSlotRec should be kept in font units. See FT_GlyphSlotRec for
+ details.
+
+
+.. data:: FT_LOAD_NO_AUTOHINT
+
+ Disable auto-hinter. See also the note below.
+
diff --git a/third_party/freetype-py/doc/ft_load_targets.rst b/third_party/freetype-py/doc/ft_load_targets.rst
new file mode 100644
index 0000000..63da52b
--- /dev/null
+++ b/third_party/freetype-py/doc/ft_load_targets.rst
@@ -0,0 +1,48 @@
+FT_LOAD_TARGETS
+===============
+
+A list of values that are used to select a specific hinting algorithm to use
+by the hinter. You should OR one of these values to your 'load_flags' when
+calling FT_Load_Glyph.
+
+Note that font's native hinters may ignore the hinting algorithm you have
+specified (e.g., the TrueType bytecode interpreter). You can set
+.. data:: FT_LOAD_FORCE_AUTOHINT to ensure that the auto-hinter is used.
+
+Also note that FT_LOAD_TARGET_LIGHT is an exception, in that it always
+implies FT_LOAD_FORCE_AUTOHINT.
+
+
+.. data:: FT_LOAD_TARGET_NORMAL
+
+ This corresponds to the default hinting algorithm, optimized for standard
+ gray-level rendering. For monochrome output, use FT_LOAD_TARGET_MONO instead.
+
+
+.. data:: FT_LOAD_TARGET_LIGHT
+
+ A lighter hinting algorithm for non-monochrome modes. Many generated glyphs
+ are more fuzzy but better resemble its original shape. A bit like rendering
+ on Mac OS X.
+
+ As a special exception, this target implies FT_LOAD_FORCE_AUTOHINT.
+
+
+.. data:: FT_LOAD_TARGET_MONO
+
+ Strong hinting algorithm that should only be used for monochrome output. The
+ result is probably unpleasant if the glyph is rendered in non-monochrome
+ modes.
+
+
+.. data:: FT_LOAD_TARGET_LCD
+
+ A variant of FT_LOAD_TARGET_NORMAL optimized for horizontally decimated LCD
+ displays.
+
+
+.. data:: FT_LOAD_TARGET_LCD_V
+
+ A variant of FT_LOAD_TARGET_NORMAL optimized for vertically decimated LCD
+ displays.
+
diff --git a/third_party/freetype-py/doc/ft_open_modes.rst b/third_party/freetype-py/doc/ft_open_modes.rst
new file mode 100644
index 0000000..2500104
--- /dev/null
+++ b/third_party/freetype-py/doc/ft_open_modes.rst
@@ -0,0 +1,31 @@
+FT_OPEN_MODES
+=============
+
+A list of bit-field constants used within the 'flags' field of the
+.. data:: FT_Open_Args structure.
+
+
+.. data:: FT_OPEN_MEMORY
+
+ This is a memory-based stream.
+
+
+.. data:: FT_OPEN_STREAM
+
+ Copy the stream from the 'stream' field.
+
+
+.. data:: FT_OPEN_PATHNAME
+
+ Create a new input stream from a C path name.
+
+
+.. data:: FT_OPEN_DRIVER
+
+ Use the 'driver' field.
+
+
+.. data:: FT_OPEN_PARAMS
+
+ Use the 'num_params' and 'params' fields.
+
diff --git a/third_party/freetype-py/doc/ft_outline_flags.rst b/third_party/freetype-py/doc/ft_outline_flags.rst
new file mode 100644
index 0000000..5bbc684
--- /dev/null
+++ b/third_party/freetype-py/doc/ft_outline_flags.rst
@@ -0,0 +1,69 @@
+FT_OUTLINE_FLAGS
+================
+
+A list of bit-field constants use for the flags in an outline's 'flags'
+field.
+
+
+.. data:: FT_OUTLINE_NONE
+
+ Value 0 is reserved.
+
+
+.. data:: FT_OUTLINE_OWNER
+
+ If set, this flag indicates that the outline's field arrays (i.e., 'points',
+ 'flags', and 'contours') are 'owned' by the outline object, and should thus
+ be freed when it is destroyed.
+
+
+.. data:: FT_OUTLINE_EVEN_ODD_FILL
+
+ By default, outlines are filled using the non-zero winding rule. If set to 1,
+ the outline will be filled using the even-odd fill rule (only works with the
+ smooth rasterizer).
+
+
+.. data:: FT_OUTLINE_REVERSE_FILL
+
+ By default, outside contours of an outline are oriented in clock-wise
+ direction, as defined in the TrueType specification. This flag is set if the
+ outline uses the opposite direction (typically for Type 1 fonts). This flag
+ is ignored by the scan converter.
+
+
+.. data:: FT_OUTLINE_IGNORE_DROPOUTS
+
+ By default, the scan converter will try to detect drop-outs in an outline and
+ correct the glyph bitmap to ensure consistent shape continuity. If set, this
+ flag hints the scan-line converter to ignore such cases. See below for more
+ information.
+
+
+.. data:: FT_OUTLINE_SMART_DROPOUTS
+
+ Select smart dropout control. If unset, use simple dropout control. Ignored
+ if FT_OUTLINE_IGNORE_DROPOUTS is set. See below for more information.
+
+
+.. data:: FT_OUTLINE_INCLUDE_STUBS
+
+ If set, turn pixels on for 'stubs', otherwise exclude them. Ignored if
+ FT_OUTLINE_IGNORE_DROPOUTS is set. See below for more information.
+
+
+.. data:: FT_OUTLINE_HIGH_PRECISION
+
+ This flag indicates that the scan-line converter should try to convert this
+ outline to bitmaps with the highest possible quality. It is typically set for
+ small character sizes. Note that this is only a hint that might be completely
+ ignored by a given scan-converter.
+
+
+.. data:: FT_OUTLINE_SINGLE_PASS
+
+ This flag is set to force a given scan-converter to only use a single pass
+ over the outline to render a bitmap glyph image. Normally, it is set for very
+ large character sizes. It is only a hint that might be completely ignored by
+ a given scan-converter.
+
diff --git a/third_party/freetype-py/doc/ft_pixel_modes.rst b/third_party/freetype-py/doc/ft_pixel_modes.rst
new file mode 100644
index 0000000..4f56ea9
--- /dev/null
+++ b/third_party/freetype-py/doc/ft_pixel_modes.rst
@@ -0,0 +1,55 @@
+FT_PIXEL_MODES
+==============
+
+An enumeration type that lists the render modes supported by FreeType 2. Each
+mode corresponds to a specific type of scanline conversion performed on the
+outline.
+
+
+.. data:: FT_PIXEL_MODE_NONE
+
+ Value 0 is reserved.
+
+
+.. data:: FT_PIXEL_MODE_MONO
+
+ A monochrome bitmap, using 1 bit per pixel. Note that pixels are stored in
+ most-significant order (MSB), which means that the left-most pixel in a byte
+ has value 128.
+
+
+.. data:: FT_PIXEL_MODE_GRAY
+
+ An 8-bit bitmap, generally used to represent anti-aliased glyph images. Each
+ pixel is stored in one byte. Note that the number of 'gray' levels is stored
+ in the 'num_grays' field of the FT_Bitmap structure (it generally is 256).
+
+
+.. data:: FT_PIXEL_MODE_GRAY2
+
+ A 2-bit per pixel bitmap, used to represent embedded anti-aliased bitmaps in
+ font files according to the OpenType specification. We haven't found a single
+ font using this format, however.
+
+
+.. data:: FT_PIXEL_MODE_GRAY4
+
+ A 4-bit per pixel bitmap, representing embedded anti-aliased bitmaps in font
+ files according to the OpenType specification. We haven't found a single font
+ using this format, however.
+
+
+.. data:: FT_PIXEL_MODE_LCD
+
+ An 8-bit bitmap, representing RGB or BGR decimated glyph images used for
+ display on LCD displays; the bitmap is three times wider than the original
+ glyph image. See also FT_RENDER_MODE_LCD.
+
+
+.. data:: FT_PIXEL_MODE_LCD_V
+
+ An 8-bit bitmap, representing RGB or BGR decimated glyph images used for
+ display on rotated LCD displays; the bitmap is three times taller than the
+ original glyph image. See also FT_RENDER_MODE_LCD_V.
+
+
diff --git a/third_party/freetype-py/doc/ft_render_modes.rst b/third_party/freetype-py/doc/ft_render_modes.rst
new file mode 100644
index 0000000..fd9027b
--- /dev/null
+++ b/third_party/freetype-py/doc/ft_render_modes.rst
@@ -0,0 +1,45 @@
+FT_RENDER_MODES
+===============
+
+An enumeration type that lists the render modes supported by FreeType 2. Each
+mode corresponds to a specific type of scanline conversion performed on the
+outline.
+
+For bitmap fonts and embedded bitmaps the 'bitmap->pixel_mode' field in the
+.. data:: FT_GlyphSlotRec structure gives the format of the returned bitmap.
+
+All modes except FT_RENDER_MODE_MONO use 256 levels of opacity.
+
+
+.. data:: FT_RENDER_MODE_NORMAL
+
+ This is the default render mode; it corresponds to 8-bit anti-aliased
+ bitmaps.
+
+
+.. data:: FT_RENDER_MODE_LIGHT
+
+ This is equivalent to FT_RENDER_MODE_NORMAL. It is only defined as a separate
+ value because render modes are also used indirectly to define hinting
+ algorithm selectors. See FT_LOAD_TARGET_XXX for details.
+
+
+.. data:: FT_RENDER_MODE_MONO
+
+ This mode corresponds to 1-bit bitmaps (with 2 levels of opacity).
+
+
+.. data:: FT_RENDER_MODE_LCD
+
+ This mode corresponds to horizontal RGB and BGR sub-pixel displays like LCD
+ screens. It produces 8-bit bitmaps that are 3 times the width of the original
+ glyph outline in pixels, and which use the FT_PIXEL_MODE_LCD mode.
+
+
+.. data:: FT_RENDER_MODE_LCD_V
+
+ This mode corresponds to vertical RGB and BGR sub-pixel displays (like PDA
+ screens, rotated LCD displays, etc.). It produces 8-bit bitmaps that are 3
+ times the height of the original glyph outline in pixels and use the
+ FT_PIXEL_MODE_LCD_V mode.
+
diff --git a/third_party/freetype-py/doc/ft_stroker_borders.rst b/third_party/freetype-py/doc/ft_stroker_borders.rst
new file mode 100644
index 0000000..31bc073
--- /dev/null
+++ b/third_party/freetype-py/doc/ft_stroker_borders.rst
@@ -0,0 +1,27 @@
+FT_STROKER_BORDERS
+==================
+
+These values are used to select a given stroke border in
+.. data:: FT_Stroker_GetBorderCounts and FT_Stroker_ExportBorder.
+
+
+.. data:: FT_STROKER_BORDER_LEFT
+
+ Select the left border, relative to the drawing direction.
+
+
+.. data:: FT_STROKER_BORDER_RIGHT
+
+ Select the right border, relative to the drawing direction.
+
+
+Note
+
+ Applications are generally interested in the 'inside' and 'outside'
+ borders. However, there is no direct mapping between these and the 'left' and
+ 'right' ones, since this really depends on the glyph's drawing orientation,
+ which varies between font formats.
+
+ You can however use FT_Outline_GetInsideBorder and
+ FT_Outline_GetOutsideBorder to get these.
+
diff --git a/third_party/freetype-py/doc/ft_stroker_linecaps.rst b/third_party/freetype-py/doc/ft_stroker_linecaps.rst
new file mode 100644
index 0000000..aa56831
--- /dev/null
+++ b/third_party/freetype-py/doc/ft_stroker_linecaps.rst
@@ -0,0 +1,21 @@
+FT_STROKER_LINECAPS
+===================
+
+These values determine how the end of opened sub-paths are rendered in a
+stroke.
+
+
+.. data:: FT_STROKER_LINECAP_BUTT
+
+ The end of lines is rendered as a full stop on the last point itself.
+
+
+.. data:: FT_STROKER_LINECAP_ROUND
+
+ The end of lines is rendered as a half-circle around the last point.
+
+
+.. data:: FT_STROKER_LINECAP_SQUARE
+
+ The end of lines is rendered as a square around the last point.
+
diff --git a/third_party/freetype-py/doc/ft_stroker_linejoins.rst b/third_party/freetype-py/doc/ft_stroker_linejoins.rst
new file mode 100644
index 0000000..dcbdf28
--- /dev/null
+++ b/third_party/freetype-py/doc/ft_stroker_linejoins.rst
@@ -0,0 +1,24 @@
+FT_STROKER_LINEJOINS
+====================
+
+These values determine how two joining lines are rendered in a stroker.
+
+
+.. data:: FT_STROKER_LINEJOIN_ROUND
+
+ Used to render rounded line joins. Circular arcs are used to join two lines
+ smoothly.
+
+
+.. data:: FT_STROKER_LINEJOIN_BEVEL
+
+ Used to render beveled line joins; i.e., the two joining lines are extended
+ until they intersect.
+
+
+.. data:: FT_STROKER_LINEJOIN_MITER
+
+ Same as beveled rendering, except that an additional line break is added if
+ the angle between the two joining lines is too closed (this is useful to
+ avoid unpleasant spikes in beveled rendering).
+
diff --git a/third_party/freetype-py/doc/ft_style_flags.rst b/third_party/freetype-py/doc/ft_style_flags.rst
new file mode 100644
index 0000000..9cf532c
--- /dev/null
+++ b/third_party/freetype-py/doc/ft_style_flags.rst
@@ -0,0 +1,16 @@
+FT_STYLE_FLAGS
+==============
+
+A list of bit-flags used to indicate the style of a given face. These are
+used in the 'style_flags' field of FT_FaceRec.
+
+
+.. data:: FT_STYLE_FLAG_ITALIC
+
+ Indicates that a given face style is italic or oblique.
+
+
+.. data:: FT_STYLE_FLAG_BOLD
+
+ Indicates that a given face is bold.
+
diff --git a/third_party/freetype-py/doc/glyph.rst b/third_party/freetype-py/doc/glyph.rst
new file mode 100644
index 0000000..9bfa079
--- /dev/null
+++ b/third_party/freetype-py/doc/glyph.rst
@@ -0,0 +1,6 @@
+.. currentmodule:: freetype
+
+Glyph
+=====
+.. autoclass:: Glyph
+ :members:
diff --git a/third_party/freetype-py/doc/glyph_slot.rst b/third_party/freetype-py/doc/glyph_slot.rst
new file mode 100644
index 0000000..eea03c2
--- /dev/null
+++ b/third_party/freetype-py/doc/glyph_slot.rst
@@ -0,0 +1,6 @@
+.. currentmodule:: freetype
+
+Glyph slot
+==========
+.. autoclass:: GlyphSlot
+ :members:
diff --git a/third_party/freetype-py/doc/index.rst b/third_party/freetype-py/doc/index.rst
new file mode 100644
index 0000000..5e5d358
--- /dev/null
+++ b/third_party/freetype-py/doc/index.rst
@@ -0,0 +1,26 @@
+=============================
+Freetype python documentation
+=============================
+
+Freetype python provides bindings for the FreeType library. Only the high-level API is bound.
+
+Freetype-py lives at https://github.com/rougier/freetype-py/
+
+
+.. toctree::
+ :maxdepth: 1
+
+ introduction.rst
+ usage.rst
+ screenshots.rst
+ api.rst
+ notes.rst
+ license.rst
+
+
+Indices and tables
+==================
+
+* :ref:`genindex`
+* :ref:`modindex`
+* :ref:`search`
diff --git a/third_party/freetype-py/doc/introduction.rst b/third_party/freetype-py/doc/introduction.rst
new file mode 100644
index 0000000..f7ed63d
--- /dev/null
+++ b/third_party/freetype-py/doc/introduction.rst
@@ -0,0 +1,53 @@
+============
+Introduction
+============
+
+To be able to use freetype python, you need the freetype library version 2
+installed on your system.
+
+
+Pre-requisites
+==============
+
+You need to have the Freetype library installed on your system to be able to use
+the freetype python bindings.
+
+.. warning::
+
+ If you don't compile the Freetype library yourself, chances are subpixel
+ anti-aliasing will be disabled due to patent problems. Have a look at
+ `Freetype FAQ <http://www.freetype.org/freetype2/docs/ft2faq.html#builds>`_
+ to know how to enable it.
+
+Mac users
+---------
+Freetype should be already installed on your system. If not, either install it
+using `homebrew <http://brew.sh>`_ or compile it and place the library binary
+file in '/usr/local/lib'.
+
+Linux users
+-----------
+Freetype should be already installed on your system. If not, either install
+relevant package from your package manager or compile from sources and place
+the library binary file in '/usr/local/lib'.
+
+Window users
+------------
+You can try to install a window binaries available from the Freetype site or
+you can compile it from sources. In such a case, make sure the resulting
+library binaries is named 'Freetype.dll' (and not something like
+Freetype245.dll) and make sure to place a copy in Windows/System32 directory.
+
+
+Installation
+============
+
+The easiest way to install freetype-pu is to use pip::
+
+ pip install freetype-py
+
+Or you can get the latest version from git and install yourself::
+
+ git clone https://github.com/rougier/freetype-py.git
+ cd freetype-py
+ python setup.py install
diff --git a/third_party/freetype-py/doc/license.rst b/third_party/freetype-py/doc/license.rst
new file mode 100644
index 0000000..8d980b5
--- /dev/null
+++ b/third_party/freetype-py/doc/license.rst
@@ -0,0 +1,29 @@
+License
+=======
+
+Copyright (c) 2011-2014, Nicolas P. Rougier - All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+Redistributions of source code must retain the above copyright notice, this
+list of conditions and the following disclaimer.
+
+Redistributions in binary form must reproduce the above copyright notice, this
+list of conditions and the following disclaimer in the documentation and/or
+other materials provided with the distribution.
+
+Neither the name of the freetype-py Development Team nor the names of its
+contributors may be used to endorse or promote products derived from this
+software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/third_party/freetype-py/doc/make.bat b/third_party/freetype-py/doc/make.bat
new file mode 100644
index 0000000..240f628
--- /dev/null
+++ b/third_party/freetype-py/doc/make.bat
@@ -0,0 +1,170 @@
+@ECHO OFF
+
+REM Command file for Sphinx documentation
+
+if "%SPHINXBUILD%" == "" (
+ set SPHINXBUILD=sphinx-build
+)
+set BUILDDIR=_build
+set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% .
+if NOT "%PAPER%" == "" (
+ set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
+)
+
+if "%1" == "" goto help
+
+if "%1" == "help" (
+ :help
+ echo.Please use `make ^<target^>` where ^<target^> is one of
+ echo. html to make standalone HTML files
+ echo. dirhtml to make HTML files named index.html in directories
+ echo. singlehtml to make a single large HTML file
+ echo. pickle to make pickle files
+ echo. json to make JSON files
+ echo. htmlhelp to make HTML files and a HTML help project
+ echo. qthelp to make HTML files and a qthelp project
+ echo. devhelp to make HTML files and a Devhelp project
+ echo. epub to make an epub
+ echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter
+ echo. text to make text files
+ echo. man to make manual pages
+ echo. changes to make an overview over all changed/added/deprecated items
+ echo. linkcheck to check all external links for integrity
+ echo. doctest to run all doctests embedded in the documentation if enabled
+ goto end
+)
+
+if "%1" == "clean" (
+ for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
+ del /q /s %BUILDDIR%\*
+ goto end
+)
+
+if "%1" == "html" (
+ %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The HTML pages are in %BUILDDIR%/html.
+ goto end
+)
+
+if "%1" == "dirhtml" (
+ %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
+ goto end
+)
+
+if "%1" == "singlehtml" (
+ %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.
+ goto end
+)
+
+if "%1" == "pickle" (
+ %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished; now you can process the pickle files.
+ goto end
+)
+
+if "%1" == "json" (
+ %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished; now you can process the JSON files.
+ goto end
+)
+
+if "%1" == "htmlhelp" (
+ %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished; now you can run HTML Help Workshop with the ^
+.hhp project file in %BUILDDIR%/htmlhelp.
+ goto end
+)
+
+if "%1" == "qthelp" (
+ %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished; now you can run "qcollectiongenerator" with the ^
+.qhcp project file in %BUILDDIR%/qthelp, like this:
+ echo.^> qcollectiongenerator %BUILDDIR%\qthelp\FreetypePython.qhcp
+ echo.To view the help file:
+ echo.^> assistant -collectionFile %BUILDDIR%\qthelp\FreetypePython.ghc
+ goto end
+)
+
+if "%1" == "devhelp" (
+ %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished.
+ goto end
+)
+
+if "%1" == "epub" (
+ %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The epub file is in %BUILDDIR%/epub.
+ goto end
+)
+
+if "%1" == "latex" (
+ %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
+ goto end
+)
+
+if "%1" == "text" (
+ %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The text files are in %BUILDDIR%/text.
+ goto end
+)
+
+if "%1" == "man" (
+ %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The manual pages are in %BUILDDIR%/man.
+ goto end
+)
+
+if "%1" == "changes" (
+ %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.The overview file is in %BUILDDIR%/changes.
+ goto end
+)
+
+if "%1" == "linkcheck" (
+ %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Link check complete; look for any errors in the above output ^
+or in %BUILDDIR%/linkcheck/output.txt.
+ goto end
+)
+
+if "%1" == "doctest" (
+ %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Testing of doctests in the sources finished, look at the ^
+results in %BUILDDIR%/doctest/output.txt.
+ goto end
+)
+
+:end
diff --git a/third_party/freetype-py/doc/make_enums.py b/third_party/freetype-py/doc/make_enums.py
new file mode 100644
index 0000000..f87c677
--- /dev/null
+++ b/third_party/freetype-py/doc/make_enums.py
@@ -0,0 +1,48 @@
+import freetype
+
+enums = [
+ 'ft_fstypes',
+ 'ft_face_flags',
+ 'ft_encodings',
+ 'ft_glyph_bbox_modes',
+ 'ft_glyph_formats',
+ 'ft_kerning_modes',
+ 'ft_lcd_filters',
+ 'ft_load_flags',
+ 'ft_load_targets',
+ 'ft_open_modes',
+ 'ft_outline_flags',
+ 'ft_pixel_modes',
+ 'ft_render_modes',
+ 'ft_stroker_borders',
+ 'ft_stroker_linecaps',
+ 'ft_stroker_linejoins',
+ 'ft_style_flags',
+ 'tt_adobe_ids',
+ 'tt_apple_ids',
+ 'tt_mac_ids',
+ 'tt_ms_ids',
+ 'tt_ms_langids',
+ 'tt_mac_langids',
+ 'tt_name_ids',
+ 'tt_platforms'
+]
+
+for name in enums:
+ print name
+ module = getattr(freetype, name)
+ doc = getattr(module, '__doc__')
+ doc = doc.split('\n')
+ file = open( name+'.rst', 'w')
+
+ title = name.upper()
+ file.write(title+'\n')
+ file.write('='*len(title)+'\n')
+
+ for line in doc:
+ if line.startswith('FT_') or line.startswith('TT_'):
+ file.write( '.. data:: '+ line + '\n')
+ else:
+ file.write( line + '\n')
+ file.close()
+
diff --git a/third_party/freetype-py/doc/notes.rst b/third_party/freetype-py/doc/notes.rst
new file mode 100644
index 0000000..95eeba7
--- /dev/null
+++ b/third_party/freetype-py/doc/notes.rst
@@ -0,0 +1,44 @@
+=============
+Release notes
+=============
+
+0.4.1
+=====
+* Fixed a bug in Face.load_char
+* Added get_format and get_fstype in Face (titusz.pan)
+
+0.3.3
+=====
+* Fixed a bug in get_kerning
+* Added test against freetype version for FT_ReferenceFace and FT_Get_FSType_Flags
+
+0.3.2
+=====
+* Added wordle.py example
+* Added get_bbox for Outline class
+* Added get_cbox for Outline and Glyph classes
+* Added __del__ method to Face class
+* Set encoding (utf-8) to all source files and examples.
+* Added test against freetype version for FT_Library_SetLcdFilterWeights.
+
+0.3.1
+=====
+* Added FT_Stroker bindings (enums, structs and methods)
+* Added ft-outline and ft-color examples
+* Fixed first/next char in Face
+* Pythonic interface has been documented
+
+0.3.0
+=====
+* Added ftdump.py demo and necessary functions
+
+0.2.0
+=====
+* Added sfnt functions
+* Added TT_XXX flags in ft_enums
+* New examples
+
+0.1.1
+=====
+* Initial release
+* Working examples
diff --git a/third_party/freetype-py/doc/outline.rst b/third_party/freetype-py/doc/outline.rst
new file mode 100644
index 0000000..6c187c0
--- /dev/null
+++ b/third_party/freetype-py/doc/outline.rst
@@ -0,0 +1,6 @@
+.. currentmodule:: freetype
+
+Outline
+=======
+.. autoclass:: Outline
+ :members:
diff --git a/third_party/freetype-py/doc/screenshots.rst b/third_party/freetype-py/doc/screenshots.rst
new file mode 100644
index 0000000..d1f0c54
--- /dev/null
+++ b/third_party/freetype-py/doc/screenshots.rst
@@ -0,0 +1,34 @@
+===========
+Screenshots
+===========
+
+Screenshot below comes from the wordle.py example. No clever tricks here, just
+brute force.
+
+.. image:: _static/wordle.png
+
+Screenshots below comes from the glyph-vector.py and glyph-vectopr-2.py
+examples showing how to access a glyph outline information and use it to draw
+the glyph. Rendering (with Bézier curves) is done using matplotlib.
+
+.. image:: _static/S.png
+.. image:: _static/G.png
+
+
+Screenshot below comes from the glyph-color.py showing how to draw and combine
+a glyph outline with the regular glyph.
+
+.. image:: _static/outline.png
+
+The screenshot below comes from the hello-world.py example showing how to draw
+text in a bitmap (that has been zoomed in to show antialiasing).
+
+.. image:: _static/hello-world.png
+
+
+The screenshot below comes from the agg-trick.py example showing an
+implementation of ideas from the `Texts Rasterization Exposures
+<http://agg.sourceforge.net/antigrain.com/research/font_rasterization/>`_ by
+Maxim Shemarev.
+
+.. image:: _static/agg-trick.png
diff --git a/third_party/freetype-py/doc/sfnt_name.rst b/third_party/freetype-py/doc/sfnt_name.rst
new file mode 100644
index 0000000..95aaefd
--- /dev/null
+++ b/third_party/freetype-py/doc/sfnt_name.rst
@@ -0,0 +1,6 @@
+.. currentmodule:: freetype
+
+SFNT name
+==========
+.. autoclass:: SfntName
+ :members:
diff --git a/third_party/freetype-py/doc/size_metrics.rst b/third_party/freetype-py/doc/size_metrics.rst
new file mode 100644
index 0000000..9f2e489
--- /dev/null
+++ b/third_party/freetype-py/doc/size_metrics.rst
@@ -0,0 +1,6 @@
+.. currentmodule:: freetype
+
+Size Metrics
+============
+.. autoclass:: SizeMetrics
+ :members:
diff --git a/third_party/freetype-py/doc/stroker.rst b/third_party/freetype-py/doc/stroker.rst
new file mode 100644
index 0000000..27a2a25
--- /dev/null
+++ b/third_party/freetype-py/doc/stroker.rst
@@ -0,0 +1,6 @@
+.. currentmodule:: freetype
+
+Stroker
+=======
+.. autoclass:: Stroker
+ :members:
diff --git a/third_party/freetype-py/doc/tt_adobe_ids.rst b/third_party/freetype-py/doc/tt_adobe_ids.rst
new file mode 100644
index 0000000..bcc6e58
--- /dev/null
+++ b/third_party/freetype-py/doc/tt_adobe_ids.rst
@@ -0,0 +1,25 @@
+TT_ADOBE_IDS
+============
+
+A list of valid values for the 'encoding_id' for TT_PLATFORM_ADOBE
+charmaps. This is a FreeType-specific extension!
+
+.. data:: TT_ADOBE_ID_STANDARD
+
+ Adobe standard encoding.
+
+
+.. data:: TT_ADOBE_ID_EXPERT
+
+ Adobe expert encoding.
+
+
+.. data:: TT_ADOBE_ID_CUSTOM
+
+ Adobe custom encoding.
+
+
+.. data:: TT_ADOBE_ID_LATIN_1
+
+ Adobe Latin 1 encoding.
+
diff --git a/third_party/freetype-py/doc/tt_apple_ids.rst b/third_party/freetype-py/doc/tt_apple_ids.rst
new file mode 100644
index 0000000..c26b825
--- /dev/null
+++ b/third_party/freetype-py/doc/tt_apple_ids.rst
@@ -0,0 +1,37 @@
+TT_APPLE_IDS
+============
+
+A list of valid values for the 'encoding_id' for TT_PLATFORM_APPLE_UNICODE
+charmaps and name entries.
+
+
+.. data:: TT_APPLE_ID_DEFAULT
+
+ Unicode version 1.0.
+
+
+.. data:: TT_APPLE_ID_UNICODE_1_1
+
+ Unicode 1.1; specifies Hangul characters starting at U+34xx.
+
+
+.. data:: TT_APPLE_ID_ISO_10646
+
+ Deprecated (identical to preceding).
+
+
+.. data:: TT_APPLE_ID_UNICODE_2_0
+
+ Unicode 2.0 and beyond (UTF-16 BMP only).
+
+
+.. data:: TT_APPLE_ID_UNICODE_32
+
+ Unicode 3.1 and beyond, using UTF-32.
+
+
+.. data:: TT_APPLE_ID_VARIANT_SELECTOR
+
+ From Adobe, not Apple. Not a normal cmap. Specifies variations on a real
+ cmap.
+
diff --git a/third_party/freetype-py/doc/tt_mac_ids.rst b/third_party/freetype-py/doc/tt_mac_ids.rst
new file mode 100644
index 0000000..5b7cec4
--- /dev/null
+++ b/third_party/freetype-py/doc/tt_mac_ids.rst
@@ -0,0 +1,74 @@
+TT_MAC_IDS
+==========
+
+A list of valid values for the 'encoding_id' for TT_PLATFORM_MACINTOSH
+charmaps and name entries.
+
+.. data:: TT_MAC_ID_ROMAN
+
+.. data:: TT_MAC_ID_TELUGU
+
+.. data:: TT_MAC_ID_GURMUKHI
+
+.. data:: TT_MAC_ID_TIBETAN
+
+.. data:: TT_MAC_ID_SIMPLIFIED_CHINESE
+
+.. data:: TT_MAC_ID_SINDHI
+
+.. data:: TT_MAC_ID_SINHALESE
+
+.. data:: TT_MAC_ID_RUSSIAN
+
+.. data:: TT_MAC_ID_KANNADA
+
+.. data:: TT_MAC_ID_VIETNAMESE
+
+.. data:: TT_MAC_ID_MONGOLIAN
+
+.. data:: TT_MAC_ID_DEVANAGARI
+
+.. data:: TT_MAC_ID_HEBREW
+
+.. data:: TT_MAC_ID_TAMIL
+
+.. data:: TT_MAC_ID_THAI
+
+.. data:: TT_MAC_ID_BURMESE
+
+.. data:: TT_MAC_ID_MALDIVIAN
+
+.. data:: TT_MAC_ID_TRADITIONAL_CHINESE
+
+.. data:: TT_MAC_ID_JAPANESE
+
+.. data:: TT_MAC_ID_GREEK
+
+.. data:: TT_MAC_ID_LAOTIAN
+
+.. data:: TT_MAC_ID_KHMER
+
+.. data:: TT_MAC_ID_UNINTERP
+
+.. data:: TT_MAC_ID_ORIYA
+
+.. data:: TT_MAC_ID_RSYMBOL
+
+.. data:: TT_MAC_ID_MALAYALAM
+
+.. data:: TT_MAC_ID_GEEZ
+
+.. data:: TT_MAC_ID_KOREAN
+
+.. data:: TT_MAC_ID_GUJARATI
+
+.. data:: TT_MAC_ID_BENGALI
+
+.. data:: TT_MAC_ID_ARABIC
+
+.. data:: TT_MAC_ID_GEORGIAN
+
+.. data:: TT_MAC_ID_ARMENIAN
+
+.. data:: TT_MAC_ID_SLAVIC
+
diff --git a/third_party/freetype-py/doc/tt_mac_langids.rst b/third_party/freetype-py/doc/tt_mac_langids.rst
new file mode 100644
index 0000000..0491e2a
--- /dev/null
+++ b/third_party/freetype-py/doc/tt_mac_langids.rst
@@ -0,0 +1,246 @@
+TT_MAC_LANGIDS
+==============
+
+Possible values of the language identifier field in the name records of the
+TTF 'name' table if the 'platform' identifier code is TT_PLATFORM_MACINTOSH.
+
+.. data:: TT_MAC_LANGID_LATIN
+
+.. data:: TT_MAC_LANGID_MALAY_ARABIC_SCRIPT
+
+.. data:: TT_MAC_LANGID_HINDI
+
+.. data:: TT_MAC_LANGID_CATALAN
+
+.. data:: TT_MAC_LANGID_MARATHI
+
+.. data:: TT_MAC_LANGID_ICELANDIC
+
+.. data:: TT_MAC_LANGID_ARABIC
+
+.. data:: TT_MAC_LANGID_SWAHILI
+
+.. data:: TT_MAC_LANGID_KHMER
+
+.. data:: TT_MAC_LANGID_UKRAINIAN
+
+.. data:: TT_MAC_LANGID_FINNISH
+
+.. data:: TT_MAC_LANGID_POLISH
+
+.. data:: TT_MAC_LANGID_NEPALI
+
+.. data:: TT_MAC_LANGID_UZBEK
+
+.. data:: TT_MAC_LANGID_TELUGU
+
+.. data:: TT_MAC_LANGID_MALTESE
+
+.. data:: TT_MAC_LANGID_AFRIKAANS
+
+.. data:: TT_MAC_LANGID_CHEWA
+
+.. data:: TT_MAC_LANGID_BASQUE
+
+.. data:: TT_MAC_LANGID_CZECH
+
+.. data:: TT_MAC_LANGID_ROMANIAN
+
+.. data:: TT_MAC_LANGID_QUECHUA
+
+.. data:: TT_MAC_LANGID_TAGALOG
+
+.. data:: TT_MAC_LANGID_HUNGARIAN
+
+.. data:: TT_MAC_LANGID_AZERBAIJANI_CYRILLIC_SCRIPT
+
+.. data:: TT_MAC_LANGID_TONGAN
+
+.. data:: TT_MAC_LANGID_SUNDANESE
+
+.. data:: TT_MAC_LANGID_JAPANESE
+
+.. data:: TT_MAC_LANGID_MONGOLIAN
+
+.. data:: TT_MAC_LANGID_ALBANIAN
+
+.. data:: TT_MAC_LANGID_NORWEGIAN
+
+.. data:: TT_MAC_LANGID_SLOVAK
+
+.. data:: TT_MAC_LANGID_MALAGASY
+
+.. data:: TT_MAC_LANGID_DZONGKHA
+
+.. data:: TT_MAC_LANGID_DUTCH
+
+.. data:: TT_MAC_LANGID_MALAY_ROMAN_SCRIPT
+
+.. data:: TT_MAC_LANGID_SERBIAN
+
+.. data:: TT_MAC_LANGID_GERMAN
+
+.. data:: TT_MAC_LANGID_SOMALI
+
+.. data:: TT_MAC_LANGID_KOREAN
+
+.. data:: TT_MAC_LANGID_MONGOLIAN_MONGOLIAN_SCRIPT
+
+.. data:: TT_MAC_LANGID_CROATIAN
+
+.. data:: TT_MAC_LANGID_TURKISH
+
+.. data:: TT_MAC_LANGID_MOLDAVIAN
+
+.. data:: TT_MAC_LANGID_LAO
+
+.. data:: TT_MAC_LANGID_ORIYA
+
+.. data:: TT_MAC_LANGID_BRETON
+
+.. data:: TT_MAC_LANGID_PASHTO
+
+.. data:: TT_MAC_LANGID_GUARANI
+
+.. data:: TT_MAC_LANGID_HEBREW
+
+.. data:: TT_MAC_LANGID_SLOVENIAN
+
+.. data:: TT_MAC_LANGID_ESTONIAN
+
+.. data:: TT_MAC_LANGID_RUNDI
+
+.. data:: TT_MAC_LANGID_URDU
+
+.. data:: TT_MAC_LANGID_CHINESE_TRADITIONAL
+
+.. data:: TT_MAC_LANGID_TATAR
+
+.. data:: TT_MAC_LANGID_CHINESE_SIMPLIFIED
+
+.. data:: TT_MAC_LANGID_AZERBAIJANI_ARABIC_SCRIPT
+
+.. data:: TT_MAC_LANGID_SANSKRIT
+
+.. data:: TT_MAC_LANGID_KURDISH
+
+.. data:: TT_MAC_LANGID_FAEROESE
+
+.. data:: TT_MAC_LANGID_MONGOLIAN_CYRILLIC_SCRIPT
+
+.. data:: TT_MAC_LANGID_TIGRINYA
+
+.. data:: TT_MAC_LANGID_THAI
+
+.. data:: TT_MAC_LANGID_DANISH
+
+.. data:: TT_MAC_LANGID_KAZAKH
+
+.. data:: TT_MAC_LANGID_YIDDISH
+
+.. data:: TT_MAC_LANGID_ESPERANTO
+
+.. data:: TT_MAC_LANGID_LITHUANIAN
+
+.. data:: TT_MAC_LANGID_FARSI
+
+.. data:: TT_MAC_LANGID_LETTISH
+
+.. data:: TT_MAC_LANGID_VIETNAMESE
+
+.. data:: TT_MAC_LANGID_PORTUGUESE
+
+.. data:: TT_MAC_LANGID_IRISH
+
+.. data:: TT_MAC_LANGID_WELSH
+
+.. data:: TT_MAC_LANGID_PUNJABI
+
+.. data:: TT_MAC_LANGID_GREEK
+
+.. data:: TT_MAC_LANGID_INUKTITUT
+
+.. data:: TT_MAC_LANGID_FRENCH
+
+.. data:: TT_MAC_LANGID_GREEK_POLYTONIC
+
+.. data:: TT_MAC_LANGID_AZERBAIJANI
+
+.. data:: TT_MAC_LANGID_JAVANESE
+
+.. data:: TT_MAC_LANGID_SWEDISH
+
+.. data:: TT_MAC_LANGID_UIGHUR
+
+.. data:: TT_MAC_LANGID_BENGALI
+
+.. data:: TT_MAC_LANGID_RUANDA
+
+.. data:: TT_MAC_LANGID_SINDHI
+
+.. data:: TT_MAC_LANGID_TIBETAN
+
+.. data:: TT_MAC_LANGID_ENGLISH
+
+.. data:: TT_MAC_LANGID_SAAMISK
+
+.. data:: TT_MAC_LANGID_INDONESIAN
+
+.. data:: TT_MAC_LANGID_MANX_GAELIC
+
+.. data:: TT_MAC_LANGID_BYELORUSSIAN
+
+.. data:: TT_MAC_LANGID_BULGARIAN
+
+.. data:: TT_MAC_LANGID_GEORGIAN
+
+.. data:: TT_MAC_LANGID_AZERBAIJANI_ROMAN_SCRIPT
+
+.. data:: TT_MAC_LANGID_ITALIAN
+
+.. data:: TT_MAC_LANGID_SCOTTISH_GAELIC
+
+.. data:: TT_MAC_LANGID_ARMENIAN
+
+.. data:: TT_MAC_LANGID_GALLA
+
+.. data:: TT_MAC_LANGID_MACEDONIAN
+
+.. data:: TT_MAC_LANGID_IRISH_GAELIC
+
+.. data:: TT_MAC_LANGID_KIRGHIZ
+
+.. data:: TT_MAC_LANGID_TAMIL
+
+.. data:: TT_MAC_LANGID_SPANISH
+
+.. data:: TT_MAC_LANGID_BURMESE
+
+.. data:: TT_MAC_LANGID_KANNADA
+
+.. data:: TT_MAC_LANGID_GALICIAN
+
+.. data:: TT_MAC_LANGID_FLEMISH
+
+.. data:: TT_MAC_LANGID_TAJIKI
+
+.. data:: TT_MAC_LANGID_ASSAMESE
+
+.. data:: TT_MAC_LANGID_SINHALESE
+
+.. data:: TT_MAC_LANGID_GREELANDIC
+
+.. data:: TT_MAC_LANGID_AMHARIC
+
+.. data:: TT_MAC_LANGID_KASHMIRI
+
+.. data:: TT_MAC_LANGID_AYMARA
+
+.. data:: TT_MAC_LANGID_GUJARATI
+
+.. data:: TT_MAC_LANGID_RUSSIAN
+
+.. data:: TT_MAC_LANGID_TURKMEN
+
+.. data:: TT_MAC_LANGID_MALAYALAM
+
diff --git a/third_party/freetype-py/doc/tt_ms_ids.rst b/third_party/freetype-py/doc/tt_ms_ids.rst
new file mode 100644
index 0000000..ede063c
--- /dev/null
+++ b/third_party/freetype-py/doc/tt_ms_ids.rst
@@ -0,0 +1,49 @@
+TT_MS_IDS
+=========
+
+A list of valid values for the 'encoding_id' for TT_PLATFORM_MICROSOFT
+charmaps and name entries.
+
+
+.. data:: TT_MS_ID_SYMBOL_CS
+
+ Corresponds to Microsoft symbol encoding. See FT_ENCODING_MS_SYMBOL.
+
+
+.. data:: TT_MS_ID_UNICODE_CS
+
+ Corresponds to a Microsoft WGL4 charmap, matching Unicode. See
+ FT_ENCODING_UNICODE.
+
+
+.. data:: TT_MS_ID_SJIS
+
+ Corresponds to SJIS Japanese encoding. See FT_ENCODING_SJIS.
+
+
+.. data:: TT_MS_ID_GB2312
+
+ Corresponds to Simplified Chinese as used in Mainland China. See
+ FT_ENCODING_GB2312.
+
+
+.. data:: TT_MS_ID_BIG_5
+
+ Corresponds to Traditional Chinese as used in Taiwan and Hong Kong. See
+ FT_ENCODING_BIG5.
+
+
+.. data:: TT_MS_ID_WANSUNG
+
+ Corresponds to Korean Wansung encoding. See FT_ENCODING_WANSUNG.
+
+.. data:: TT_MS_ID_JOHAB
+
+ Corresponds to Johab encoding. See FT_ENCODING_JOHAB.
+
+
+.. data:: TT_MS_ID_UCS_4
+
+ Corresponds to UCS-4 or UTF-32 charmaps. This has been added to the OpenType
+ specification version 1.4 (mid-2001.)
+
diff --git a/third_party/freetype-py/doc/tt_ms_langids.rst b/third_party/freetype-py/doc/tt_ms_langids.rst
new file mode 100644
index 0000000..bd0a71f
--- /dev/null
+++ b/third_party/freetype-py/doc/tt_ms_langids.rst
@@ -0,0 +1,496 @@
+TT_MS_LANGIDS
+=============
+
+Possible values of the language identifier field in the name records of the
+TTF 'name' table if the 'platform' identifier code is TT_PLATFORM_MICROSOFT.
+
+.. data:: TT_MS_LANGID_SANSKRIT_INDIA
+
+.. data:: TT_MS_LANGID_ENGLISH_UNITED_KINGDOM
+
+.. data:: TT_MS_LANGID_ENGLISH_BELIZE
+
+.. data:: TT_MS_LANGID_ARABIC_LEBANON
+
+.. data:: TT_MS_LANGID_MOLDAVIAN_MOLDAVIA
+
+.. data:: TT_MS_LANGID_TURKISH_TURKEY
+
+.. data:: TT_MS_LANGID_WELSH_WALES
+
+.. data:: TT_MS_LANGID_GERMAN_AUSTRIA
+
+.. data:: TT_MS_LANGID_DUTCH_BELGIUM
+
+.. data:: TT_MS_LANGID_YI_CHINA
+
+.. data:: TT_MS_LANGID_QUECHUA_ECUADOR
+
+.. data:: TT_MS_LANGID_SPANISH_EL_SALVADOR
+
+.. data:: TT_MS_LANGID_SWAHILI_KENYA
+
+.. data:: TT_MS_LANGID_QUECHUA_BOLIVIA
+
+.. data:: TT_MS_LANGID_SLOVENE_SLOVENIA
+
+.. data:: TT_MS_LANGID_ORIYA_INDIA
+
+.. data:: TT_MS_LANGID_FARSI_IRAN
+
+.. data:: TT_MS_LANGID_ENGLISH_CANADA
+
+.. data:: TT_MS_LANGID_NEPALI_NEPAL
+
+.. data:: TT_MS_LANGID_DHIVEHI_MALDIVES
+
+.. data:: TT_MS_LANGID_GERMAN_LIECHTENSTEI
+
+.. data:: TT_MS_LANGID_TAMIL_INDIA
+
+.. data:: TT_MS_LANGID_ARABIC_UAE
+
+.. data:: TT_MS_LANGID_JAPANESE_JAPAN
+
+.. data:: TT_MS_LANGID_TAMAZIGHT_MOROCCO
+
+.. data:: TT_MS_LANGID_FRENCH_FRANCE
+
+.. data:: TT_MS_LANGID_CHINESE_MACAU
+
+.. data:: TT_MS_LANGID_VIETNAMESE_VIET_NAM
+
+.. data:: TT_MS_LANGID_HEBREW_ISRAEL
+
+.. data:: TT_MS_LANGID_SAMI_NORTHERN_SWEDEN
+
+.. data:: TT_MS_LANGID_PUNJABI_ARABIC_PAKISTAN
+
+.. data:: TT_MS_LANGID_SWEDISH_SWEDEN
+
+.. data:: TT_MS_LANGID_FRENCH_REUNION
+
+.. data:: TT_MS_LANGID_ARABIC_BAHRAIN
+
+.. data:: TT_MS_LANGID_ENGLISH_INDIA
+
+.. data:: TT_MS_LANGID_NEPALI_INDIA
+
+.. data:: TT_MS_LANGID_THAI_THAILAND
+
+.. data:: TT_MS_LANGID_ENGLISH_GENERAL
+
+.. data:: TT_MS_LANGID_SAMI_LULE_NORWAY
+
+.. data:: TT_MS_LANGID_ARABIC_OMAN
+
+.. data:: TT_MS_LANGID_SPANISH_HONDURAS
+
+.. data:: TT_MS_LANGID_ENGLISH_JAMAICA
+
+.. data:: TT_MS_LANGID_ESTONIAN_ESTONIA
+
+.. data:: TT_MS_LANGID_FRISIAN_NETHERLANDS
+
+.. data:: TT_MS_LANGID_LATIN
+
+.. data:: TT_MS_LANGID_ENGLISH_INDONESIA
+
+.. data:: TT_MS_LANGID_ENGLISH_IRELAND
+
+.. data:: TT_MS_LANGID_TIBETAN_CHINA
+
+.. data:: TT_MS_LANGID_PUNJABI_INDIA
+
+.. data:: TT_MS_LANGID_FRENCH_MALI
+
+.. data:: TT_MS_LANGID_GERMAN_LUXEMBOURG
+
+.. data:: TT_MS_LANGID_SUTU_SOUTH_AFRICA
+
+.. data:: TT_MS_LANGID_FRENCH_CAMEROON
+
+.. data:: TT_MS_LANGID_FRENCH_CONGO
+
+.. data:: TT_MS_LANGID_CLASSIC_LITHUANIAN_LITHUANIA
+
+.. data:: TT_MS_LANGID_MALAYALAM_INDIA
+
+.. data:: TT_MS_LANGID_SAMI_SOUTHERN_SWEDEN
+
+.. data:: TT_MS_LANGID_CHEROKEE_UNITED_STATES
+
+.. data:: TT_MS_LANGID_SPANISH_GUATEMALA
+
+.. data:: TT_MS_LANGID_CZECH_CZECH_REPUBLIC
+
+.. data:: TT_MS_LANGID_MANIPURI_INDIA
+
+.. data:: TT_MS_LANGID_ENGLISH_AUSTRALIA
+
+.. data:: TT_MS_LANGID_SPANISH_DOMINICAN_REPUBLIC
+
+.. data:: TT_MS_LANGID_ARABIC_LIBYA
+
+.. data:: TT_MS_LANGID_FRENCH_WEST_INDIES
+
+.. data:: TT_MS_LANGID_ENGLISH_TRINIDAD
+
+.. data:: TT_MS_LANGID_ARABIC_QATAR
+
+.. data:: TT_MS_LANGID_SPANISH_COLOMBIA
+
+.. data:: TT_MS_LANGID_GUARANI_PARAGUAY
+
+.. data:: TT_MS_LANGID_EDO_NIGERIA
+
+.. data:: TT_MS_LANGID_SEPEDI_SOUTH_AFRICA
+
+.. data:: TT_MS_LANGID_ENGLISH_HONG_KONG
+
+.. data:: TT_MS_LANGID_KOREAN_EXTENDED_WANSUNG_KOREA
+
+.. data:: TT_MS_LANGID_TATAR_TATARSTAN
+
+.. data:: TT_MS_LANGID_PASHTO_AFGHANISTAN
+
+.. data:: TT_MS_LANGID_KASHMIRI_PAKISTAN
+
+.. data:: TT_MS_LANGID_GALICIAN_SPAIN
+
+.. data:: TT_MS_LANGID_TAJIK_TAJIKISTAN
+
+.. data:: TT_MS_LANGID_SAMI_INARI_FINLAND
+
+.. data:: TT_MS_LANGID_KASHMIRI_SASIA
+
+.. data:: TT_MS_LANGID_SPANISH_ARGENTINA
+
+.. data:: TT_MS_LANGID_SAMI_SOUTHERN_NORWAY
+
+.. data:: TT_MS_LANGID_CROATIAN_CROATIA
+
+.. data:: TT_MS_LANGID_GUJARATI_INDIA
+
+.. data:: TT_MS_LANGID_TIBETAN_BHUTAN
+
+.. data:: TT_MS_LANGID_TIGRIGNA_ETHIOPIA
+
+.. data:: TT_MS_LANGID_FINNISH_FINLAND
+
+.. data:: TT_MS_LANGID_ENGLISH_UNITED_STATES
+
+.. data:: TT_MS_LANGID_ITALIAN_SWITZERLAND
+
+.. data:: TT_MS_LANGID_ARABIC_EGYPT
+
+.. data:: TT_MS_LANGID_SPANISH_LATIN_AMERICA
+
+.. data:: TT_MS_LANGID_LITHUANIAN_LITHUANIA
+
+.. data:: TT_MS_LANGID_ARABIC_ALGERIA
+
+.. data:: TT_MS_LANGID_MALAY_MALAYSIA
+
+.. data:: TT_MS_LANGID_ARABIC_GENERAL
+
+.. data:: TT_MS_LANGID_CHINESE_PRC
+
+.. data:: TT_MS_LANGID_BENGALI_BANGLADESH
+
+.. data:: TT_MS_LANGID_SPANISH_PERU
+
+.. data:: TT_MS_LANGID_SPANISH_SPAIN_INTERNATIONAL_SORT
+
+.. data:: TT_MS_LANGID_DIVEHI_MALDIVES
+
+.. data:: TT_MS_LANGID_LATVIAN_LATVIA
+
+.. data:: TT_MS_LANGID_TURKMEN_TURKMENISTAN
+
+.. data:: TT_MS_LANGID_XHOSA_SOUTH_AFRICA
+
+.. data:: TT_MS_LANGID_KHMER_CAMBODIA
+
+.. data:: TT_MS_LANGID_NORWEGIAN_NORWAY_NYNORSK
+
+.. data:: TT_MS_LANGID_ARABIC_MOROCCO
+
+.. data:: TT_MS_LANGID_FRENCH_SENEGAL
+
+.. data:: TT_MS_LANGID_YORUBA_NIGERIA
+
+.. data:: TT_MS_LANGID_CATALAN_SPAIN
+
+.. data:: TT_MS_LANGID_AFRIKAANS_SOUTH_AFRICA
+
+.. data:: TT_MS_LANGID_ZULU_SOUTH_AFRICA
+
+.. data:: TT_MS_LANGID_SPANISH_URUGUAY
+
+.. data:: TT_MS_LANGID_SPANISH_ECUADOR
+
+.. data:: TT_MS_LANGID_BOSNIAN_BOSNIA_HERZEGOVINA
+
+.. data:: TT_MS_LANGID_CHINESE_GENERAL
+
+.. data:: TT_MS_LANGID_SPANISH_PARAGUAY
+
+.. data:: TT_MS_LANGID_HINDI_INDIA
+
+.. data:: TT_MS_LANGID_FRENCH_LUXEMBOURG
+
+.. data:: TT_MS_LANGID_TSWANA_SOUTH_AFRICA
+
+.. data:: TT_MS_LANGID_HUNGARIAN_HUNGARY
+
+.. data:: TT_MS_LANGID_CROATIAN_BOSNIA_HERZEGOVINA
+
+.. data:: TT_MS_LANGID_ENGLISH_SINGAPORE
+
+.. data:: TT_MS_LANGID_MALTESE_MALTA
+
+.. data:: TT_MS_LANGID_SAMI_NORTHERN_FINLAND
+
+.. data:: TT_MS_LANGID_FRENCH_CANADA
+
+.. data:: TT_MS_LANGID_SAMI_LULE_SWEDEN
+
+.. data:: TT_MS_LANGID_KANURI_NIGERIA
+
+.. data:: TT_MS_LANGID_IRISH_GAELIC_IRELAND
+
+.. data:: TT_MS_LANGID_ARABIC_SAUDI_ARABIA
+
+.. data:: TT_MS_LANGID_FRENCH_HAITI
+
+.. data:: TT_MS_LANGID_SPANISH_PUERTO_RICO
+
+.. data:: TT_MS_LANGID_BURMESE_MYANMAR
+
+.. data:: TT_MS_LANGID_POLISH_POLAND
+
+.. data:: TT_MS_LANGID_PORTUGUESE_PORTUGAL
+
+.. data:: TT_MS_LANGID_ENGLISH_CARIBBEAN
+
+.. data:: TT_MS_LANGID_KIRGHIZ_KIRGHIZ_REPUBLIC
+
+.. data:: TT_MS_LANGID_ICELANDIC_ICELAND
+
+.. data:: TT_MS_LANGID_BENGALI_INDIA
+
+.. data:: TT_MS_LANGID_HAUSA_NIGERIA
+
+.. data:: TT_MS_LANGID_BASQUE_SPAIN
+
+.. data:: TT_MS_LANGID_UIGHUR_CHINA
+
+.. data:: TT_MS_LANGID_ENGLISH_MALAYSIA
+
+.. data:: TT_MS_LANGID_FRENCH_MONACO
+
+.. data:: TT_MS_LANGID_SPANISH_BOLIVIA
+
+.. data:: TT_MS_LANGID_SORBIAN_GERMANY
+
+.. data:: TT_MS_LANGID_SINDHI_INDIA
+
+.. data:: TT_MS_LANGID_CHINESE_SINGAPORE
+
+.. data:: TT_MS_LANGID_FRENCH_COTE_D_IVOIRE
+
+.. data:: TT_MS_LANGID_SPANISH_SPAIN_TRADITIONAL_SORT
+
+.. data:: TT_MS_LANGID_SERBIAN_SERBIA_CYRILLIC
+
+.. data:: TT_MS_LANGID_SAMI_SKOLT_FINLAND
+
+.. data:: TT_MS_LANGID_SERBIAN_BOSNIA_HERZ_CYRILLIC
+
+.. data:: TT_MS_LANGID_MALAY_BRUNEI_DARUSSALAM
+
+.. data:: TT_MS_LANGID_ARABIC_JORDAN
+
+.. data:: TT_MS_LANGID_MONGOLIAN_MONGOLIA_MONGOLIAN
+
+.. data:: TT_MS_LANGID_SERBIAN_SERBIA_LATIN
+
+.. data:: TT_MS_LANGID_RUSSIAN_RUSSIA
+
+.. data:: TT_MS_LANGID_ROMANIAN_ROMANIA
+
+.. data:: TT_MS_LANGID_FRENCH_NORTH_AFRICA
+
+.. data:: TT_MS_LANGID_MONGOLIAN_MONGOLIA
+
+.. data:: TT_MS_LANGID_TSONGA_SOUTH_AFRICA
+
+.. data:: TT_MS_LANGID_SOMALI_SOMALIA
+
+.. data:: TT_MS_LANGID_SAAMI_LAPONIA
+
+.. data:: TT_MS_LANGID_SPANISH_COSTA_RICA
+
+.. data:: TT_MS_LANGID_ARABIC_SYRIA
+
+.. data:: TT_MS_LANGID_SPANISH_PANAMA
+
+.. data:: TT_MS_LANGID_PAPIAMENTU_NETHERLANDS_ANTILLES
+
+.. data:: TT_MS_LANGID_ASSAMESE_INDIA
+
+.. data:: TT_MS_LANGID_SCOTTISH_GAELIC_UNITED_KINGDOM
+
+.. data:: TT_MS_LANGID_DUTCH_NETHERLANDS
+
+.. data:: TT_MS_LANGID_SINDHI_PAKISTAN
+
+.. data:: TT_MS_LANGID_MACEDONIAN_MACEDONIA
+
+.. data:: TT_MS_LANGID_KAZAK_KAZAKSTAN
+
+.. data:: TT_MS_LANGID_AZERI_AZERBAIJAN_LATIN
+
+.. data:: TT_MS_LANGID_BELARUSIAN_BELARUS
+
+.. data:: TT_MS_LANGID_FRENCH_MOROCCO
+
+.. data:: TT_MS_LANGID_SERBIAN_BOSNIA_HERZ_LATIN
+
+.. data:: TT_MS_LANGID_ALBANIAN_ALBANIA
+
+.. data:: TT_MS_LANGID_SINHALESE_SRI_LANKA
+
+.. data:: TT_MS_LANGID_SPANISH_MEXICO
+
+.. data:: TT_MS_LANGID_ENGLISH_ZIMBABWE
+
+.. data:: TT_MS_LANGID_OROMO_ETHIOPIA
+
+.. data:: TT_MS_LANGID_INDONESIAN_INDONESIA
+
+.. data:: TT_MS_LANGID_SAMI_NORTHERN_NORWAY
+
+.. data:: TT_MS_LANGID_UZBEK_UZBEKISTAN_LATIN
+
+.. data:: TT_MS_LANGID_SLOVAK_SLOVAKIA
+
+.. data:: TT_MS_LANGID_KASHMIRI_INDIA
+
+.. data:: TT_MS_LANGID_GERMAN_SWITZERLAND
+
+.. data:: TT_MS_LANGID_URDU_INDIA
+
+.. data:: TT_MS_LANGID_FAEROESE_FAEROE_ISLANDS
+
+.. data:: TT_MS_LANGID_SYRIAC_SYRIA
+
+.. data:: TT_MS_LANGID_SPANISH_CHILE
+
+.. data:: TT_MS_LANGID_FILIPINO_PHILIPPINES
+
+.. data:: TT_MS_LANGID_ARABIC_YEMEN
+
+.. data:: TT_MS_LANGID_KONKANI_INDIA
+
+.. data:: TT_MS_LANGID_AMHARIC_ETHIOPIA
+
+.. data:: TT_MS_LANGID_ENGLISH_NEW_ZEALAND
+
+.. data:: TT_MS_LANGID_RHAETO_ROMANIC_SWITZERLAND
+
+.. data:: TT_MS_LANGID_ARABIC_TUNISIA
+
+.. data:: TT_MS_LANGID_SOTHO_SOUTHERN_SOUTH_AFRICA
+
+.. data:: TT_MS_LANGID_QUECHUA_PERU
+
+.. data:: TT_MS_LANGID_DANISH_DENMARK
+
+.. data:: TT_MS_LANGID_ENGLISH_PHILIPPINES
+
+.. data:: TT_MS_LANGID_SPANISH_NICARAGUA
+
+.. data:: TT_MS_LANGID_INUKTITUT_CANADA
+
+.. data:: TT_MS_LANGID_UKRAINIAN_UKRAINE
+
+.. data:: TT_MS_LANGID_NORWEGIAN_NORWAY_BOKMAL
+
+.. data:: TT_MS_LANGID_UZBEK_UZBEKISTAN_CYRILLIC
+
+.. data:: TT_MS_LANGID_FRENCH_BELGIUM
+
+.. data:: TT_MS_LANGID_ENGLISH_SOUTH_AFRICA
+
+.. data:: TT_MS_LANGID_HAWAIIAN_UNITED_STATES
+
+.. data:: TT_MS_LANGID_ARABIC_IRAQ
+
+.. data:: TT_MS_LANGID_KANNADA_INDIA
+
+.. data:: TT_MS_LANGID_DZONGHKA_BHUTAN
+
+.. data:: TT_MS_LANGID_CHINESE_TAIWAN
+
+.. data:: TT_MS_LANGID_SPANISH_UNITED_STATES
+
+.. data:: TT_MS_LANGID_ARMENIAN_ARMENIA
+
+.. data:: TT_MS_LANGID_LAO_LAOS
+
+.. data:: TT_MS_LANGID_TIGRIGNA_ERYTREA
+
+.. data:: TT_MS_LANGID_MARATHI_INDIA
+
+.. data:: TT_MS_LANGID_ARABIC_KUWAIT
+
+.. data:: TT_MS_LANGID_TAMAZIGHT_MOROCCO_LATIN
+
+.. data:: TT_MS_LANGID_PORTUGUESE_BRAZIL
+
+.. data:: TT_MS_LANGID_TIGRIGNA_ERYTHREA
+
+.. data:: TT_MS_LANGID_GREEK_GREECE
+
+.. data:: TT_MS_LANGID_URDU_PAKISTAN
+
+.. data:: TT_MS_LANGID_KIRGHIZ_KIRGHIZSTAN
+
+.. data:: TT_MS_LANGID_YIDDISH_GERMANY
+
+.. data:: TT_MS_LANGID_GERMAN_GERMANY
+
+.. data:: TT_MS_LANGID_TELUGU_INDIA
+
+.. data:: TT_MS_LANGID_AZERI_AZERBAIJAN_CYRILLIC
+
+.. data:: TT_MS_LANGID_KOREAN_JOHAB_KOREA
+
+.. data:: TT_MS_LANGID_ITALIAN_ITALY
+
+.. data:: TT_MS_LANGID_MAORI_NEW_ZEALAND
+
+.. data:: TT_MS_LANGID_SPANISH_VENEZUELA
+
+.. data:: TT_MS_LANGID_IGBO_NIGERIA
+
+.. data:: TT_MS_LANGID_IBIBIO_NIGERIA
+
+.. data:: TT_MS_LANGID_CHINESE_HONG_KONG
+
+.. data:: TT_MS_LANGID_FRENCH_SWITZERLAND
+
+.. data:: TT_MS_LANGID_BULGARIAN_BULGARIA
+
+.. data:: TT_MS_LANGID_FULFULDE_NIGERIA
+
+.. data:: TT_MS_LANGID_RUSSIAN_MOLDAVIA
+
+.. data:: TT_MS_LANGID_VENDA_SOUTH_AFRICA
+
+.. data:: TT_MS_LANGID_GEORGIAN_GEORGIA
+
+.. data:: TT_MS_LANGID_SWEDISH_FINLAND
+
diff --git a/third_party/freetype-py/doc/tt_name_ids.rst b/third_party/freetype-py/doc/tt_name_ids.rst
new file mode 100644
index 0000000..4134db6
--- /dev/null
+++ b/third_party/freetype-py/doc/tt_name_ids.rst
@@ -0,0 +1,50 @@
+TT_NAME_IDS
+===========
+
+Possible values of the 'name' identifier field in the name records of the TTF
+'name' table. These values are platform independent.
+
+.. data:: TT_NAME_ID_COPYRIGHT
+
+.. data:: TT_NAME_ID_FONT_FAMILY
+
+.. data:: TT_NAME_ID_FONT_SUBFAMILY
+
+.. data:: TT_NAME_ID_UNIQUE_ID
+
+.. data:: TT_NAME_ID_FULL_NAME
+
+.. data:: TT_NAME_ID_VERSION_STRING
+
+.. data:: TT_NAME_ID_PS_NAME
+
+.. data:: TT_NAME_ID_TRADEMARK
+
+.. data:: TT_NAME_ID_MANUFACTURER
+
+.. data:: TT_NAME_ID_DESIGNER
+
+.. data:: TT_NAME_ID_DESCRIPTION
+
+.. data:: TT_NAME_ID_VENDOR_URL
+
+.. data:: TT_NAME_ID_DESIGNER_URL
+
+.. data:: TT_NAME_ID_LICENSE
+
+.. data:: TT_NAME_ID_LICENSE_URL
+
+.. data:: TT_NAME_ID_PREFERRED_FAMILY
+
+.. data:: TT_NAME_ID_PREFERRED_SUBFAMILY
+
+.. data:: TT_NAME_ID_MAC_FULL_NAME
+
+.. data:: TT_NAME_ID_SAMPLE_TEXT
+
+.. data:: TT_NAME_ID_CID_FINDFONT_NAME
+
+.. data:: TT_NAME_ID_WWS_FAMILY
+
+.. data:: TT_NAME_ID_WWS_SUBFAMILY
+
diff --git a/third_party/freetype-py/doc/tt_platforms.rst b/third_party/freetype-py/doc/tt_platforms.rst
new file mode 100644
index 0000000..fd9a806
--- /dev/null
+++ b/third_party/freetype-py/doc/tt_platforms.rst
@@ -0,0 +1,47 @@
+TT_PLATFORMS
+============
+
+A list of valid values for the 'platform_id' identifier code in FT_CharMapRec
+and FT_SfntName structures.
+
+
+.. data:: TT_PLATFORM_APPLE_UNICODE
+
+ Used by Apple to indicate a Unicode character map and/or name entry. See
+ TT_APPLE_ID_XXX for corresponding 'encoding_id' values. Note that name
+ entries in this format are coded as big-endian UCS-2 character codes only.
+
+
+.. data:: TT_PLATFORM_MACINTOSH
+
+ Used by Apple to indicate a MacOS-specific charmap and/or name entry. See
+ TT_MAC_ID_XXX for corresponding 'encoding_id' values. Note that most TrueType
+ fonts contain an Apple roman charmap to be usable on MacOS systems (even if
+ they contain a Microsoft charmap as well).
+
+
+.. data:: TT_PLATFORM_ISO
+
+ This value was used to specify ISO/IEC 10646 charmaps. It is however now
+ deprecated. See TT_ISO_ID_XXX for a list of corresponding 'encoding_id'
+ values.
+
+
+.. data:: TT_PLATFORM_MICROSOFT
+
+ Used by Microsoft to indicate Windows-specific charmaps. See TT_MS_ID_XXX for
+ a list of corresponding 'encoding_id' values. Note that most fonts contain a
+ Unicode charmap using (TT_PLATFORM_MICROSOFT, TT_MS_ID_UNICODE_CS).
+
+
+.. data:: TT_PLATFORM_CUSTOM
+
+ Used to indicate application-specific charmaps.
+
+
+.. data:: TT_PLATFORM_ADOBE
+
+ This value isn't part of any font format specification, but is used by
+ FreeType to report Adobe-specific charmaps in an FT_CharMapRec structure. See
+ TT_ADOBE_ID_XXX.
+
diff --git a/third_party/freetype-py/doc/usage.rst b/third_party/freetype-py/doc/usage.rst
new file mode 100644
index 0000000..8d6e40d
--- /dev/null
+++ b/third_party/freetype-py/doc/usage.rst
@@ -0,0 +1,12 @@
+=============
+Usage example
+=============
+
+.. code:: python
+
+ import freetype
+ face = freetype.Face("Vera.ttf")
+ face.set_char_size( 48*64 )
+ face.load_char('S')
+ bitmap = face.glyph.bitmap
+ print bitmap.buffer
diff --git a/third_party/freetype-py/examples/Vera.ttf b/third_party/freetype-py/examples/Vera.ttf
new file mode 100644
index 0000000..58cd6b5
--- /dev/null
+++ b/third_party/freetype-py/examples/Vera.ttf
Binary files differ
diff --git a/third_party/freetype-py/examples/VeraMono.ttf b/third_party/freetype-py/examples/VeraMono.ttf
new file mode 100644
index 0000000..139f0b4
--- /dev/null
+++ b/third_party/freetype-py/examples/VeraMono.ttf
Binary files differ
diff --git a/third_party/freetype-py/examples/agg-trick.py b/third_party/freetype-py/examples/agg-trick.py
new file mode 100644
index 0000000..c0bc134
--- /dev/null
+++ b/third_party/freetype-py/examples/agg-trick.py
@@ -0,0 +1,73 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# -----------------------------------------------------------------------------
+#
+# FreeType high-level python API - Copyright 2011 Nicolas P. Rougier
+# Distributed under the terms of the new BSD license.
+#
+# -----------------------------------------------------------------------------
+from freetype import *
+import numpy as np
+import Image
+
+
+def render(filename = "Vera.ttf", hinting = (False,False), gamma = 1.5, lcd=False):
+ text = "A Quick Brown Fox Jumps Over The Lazy Dog 0123456789"
+
+ W,H,D = 680, 280, 1
+ Z = np.zeros( (H,W), dtype=np.ubyte )
+ face = Face(filename)
+ pen = Vector(5*64, (H-10)*64)
+
+ flags = FT_LOAD_RENDER
+ if hinting[1]: flags |= FT_LOAD_FORCE_AUTOHINT
+ else: flags |= FT_LOAD_NO_HINTING
+ if hinting[0]: hres, hscale = 72, 1.0
+ else: hres, hscale = 72*10, 0.1
+ if lcd:
+ flags |= FT_LOAD_TARGET_LCD
+ Z = np.zeros( (H,W,3), dtype=np.ubyte )
+ set_lcd_filter( FT_LCD_FILTER_DEFAULT )
+
+
+ for size in range(9,23):
+ face.set_char_size( size * 64, 0, hres, 72 )
+ matrix = Matrix( int((hscale) * 0x10000L), int((0.0) * 0x10000L),
+ int((0.0) * 0x10000L), int((1.0) * 0x10000L) )
+ previous = 0
+ pen.x = 5*64
+ for current in text:
+ face.set_transform( matrix, pen )
+ face.load_char( current, flags)
+ kerning = face.get_kerning( previous, current, FT_KERNING_UNSCALED )
+ pen.x += kerning.x
+ glyph = face.glyph
+ bitmap = glyph.bitmap
+ x, y = glyph.bitmap_left, glyph.bitmap_top
+ w, h, p = bitmap.width, bitmap.rows, bitmap.pitch
+ buff = np.array(bitmap.buffer, dtype=np.ubyte).reshape((h,p))
+ if lcd:
+ Z[H-y:H-y+h,x:x+w/3].flat |= buff[:,:w].flatten()
+ else:
+ Z[H-y:H-y+h,x:x+w].flat |= buff[:,:w].flatten()
+ pen.x += glyph.advance.x
+ previous = current
+ pen.y -= (size+4)*64
+
+ # Gamma correction
+ Z = (Z/255.0)**(gamma)
+ Z = ((1-Z)*255).astype(np.ubyte)
+ if lcd:
+ I = Image.fromarray(Z, mode='RGB')
+ else:
+ I = Image.fromarray(Z, mode='L')
+
+ name = filename.split('.')[0]
+ filename = '%s-gamma(%.1f)-hinting(%d,%d)-lcd(%d).png' % (name,gamma,hinting[0],hinting[1],lcd)
+ I.save(filename)
+
+
+
+if __name__ == '__main__':
+ render('Vera.ttf', (0,1), 1.25, True)
+
diff --git a/third_party/freetype-py/examples/ascii.py b/third_party/freetype-py/examples/ascii.py
new file mode 100644
index 0000000..ce718d3
--- /dev/null
+++ b/third_party/freetype-py/examples/ascii.py
@@ -0,0 +1,121 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# -----------------------------------------------------------------------------
+#
+# FreeType high-level python API - Copyright 2011 Nicolas P. Rougier
+# Distributed under the terms of the new BSD license.
+#
+# -----------------------------------------------------------------------------
+import numpy
+import os, sys
+from freetype import *
+
+
+class ColorMap:
+ ''' A colormap is used to map scalar values to colors. It is build by
+ adding couples of (value,color) where value must be between 0 and 1.
+ The 'scale' method allows to specify the range of the colormap and
+ the 'color' method then returns a color for any value. '''
+
+ def __init__ (self, colors):
+ self.colors = colors
+ self.min = 0
+ self.max = 1
+
+ def scale (self, min, max):
+ self.min, self.max = min,max
+
+ def color (self, value):
+ ''' Return the color corresponding to value. '''
+ if not len(self.colors):
+ return (0,0,0)
+ elif len(self.colors) == 1:
+ return self.colors[0][1]
+ elif value < self.min:
+ return self.colors[0][1]
+ elif value > self.max:
+ return self.colors[-1][1]
+ value = (value-self.min)/(self.max-self.min)
+ sup_color = self.colors[0]
+ inf_color = self.colors[-1]
+ for i in range (len(self.colors)-1):
+ if value < self.colors[i+1][0]:
+ inf_color = self.colors[i]
+ sup_color = self.colors[i+1]
+ break
+ r = (value-inf_color[0]) / (sup_color[0] - inf_color[0])
+ if r < 0: r = -r
+ color = [sup_color[1][0]*r + inf_color[1][0]*(1-r),
+ sup_color[1][1]*r + inf_color[1][1]*(1-r),
+ sup_color[1][2]*r + inf_color[1][2]*(1-r)]
+ return color
+
+# Some colormaps
+CM_IceAndFire = ColorMap([(0.00, (0.0, 0.0, 1.0)),
+ (0.25, (0.0, 0.5, 1.0)),
+ (0.50, (1.0, 1.0, 1.0)),
+ (0.75, (1.0, 1.0, 0.0)),
+ (1.00, (1.0, 0.0, 0.0))])
+CM_Ice = ColorMap([(0.00, (0.0, 0.0, 1.0)),
+ (0.50, (0.5, 0.5, 1.0)),
+ (1.00, (1.0, 1.0, 1.0))])
+CM_Fire = ColorMap([(0.00, (1.0, 1.0, 1.0)),
+ (0.50, (1.0, 1.0, 0.0)),
+ (1.00, (1.0, 0.0, 0.0))])
+CM_Hot = ColorMap([(0.00, (0.0, 0.0, 0.0)),
+ (0.33, (1.0, 0.0, 0.0)),
+ (0.66, (1.0, 1.0, 0.0)),
+ (1.00, (1.0, 1.0, 1.0))])
+CM_Grey = ColorMap([(0.00, (0.0, 0.0, 0.0)),
+ (1.00, (1.0, 1.0, 1.0))])
+
+
+
+def imshow (Z, vmin=None, vmax=None, cmap=CM_Hot, show_cmap=False):
+ ''' Show a 2D numpy array using terminal colors '''
+
+ if len(Z.shape) != 2:
+ print "Cannot display non 2D array"
+ return
+
+ vmin = vmin or Z.min()
+ vmax = vmax or Z.max()
+ cmap.scale (vmin, vmax)
+
+ # Build initialization string that setup terminal colors
+ init = ''
+ for i in range(240):
+ v = cmap.min + (i/240.0)* (cmap.max - cmap.min)
+ r,g,b = cmap.color (v)
+ init += "\x1b]4;%d;rgb:%02x/%02x/%02x\x1b\\" % (16+i, int(r*255),int(g*255),int(b*255))
+
+ # Build array data string
+ data = ''
+ for i in range(Z.shape[0]):
+ for j in range(Z.shape[1]):
+ c = 16 + int( ((Z[Z.shape[0]-i-1,j]-cmap.min) / (cmap.max-cmap.min))*239)
+ if (c < 16):
+ c=16
+ elif (c > 255):
+ c=255
+ data += "\x1b[48;5;%dm " % c
+ u = cmap.max - (i/float(Z.shape[0]-1)) * ((cmap.max-cmap.min))
+ if show_cmap:
+ data += "\x1b[0m "
+ data += "\x1b[48;5;%dm " % (16 + (1-i/float(Z.shape[0]))*239)
+ data += "\x1b[0m %+.2f" % u
+ data += "\x1b[0m\n"
+ print init+data[:-1]+'\x1b[0m'
+
+
+if __name__ == '__main__':
+ face = Face('./Vera.ttf')
+ face.set_char_size( 32*64 )
+ face.load_glyph(face.get_char_index('S'))
+ slot = face.glyph
+ bitmap = slot.bitmap
+ data, rows, width = bitmap.buffer, bitmap.rows, bitmap.width
+ Z = numpy.array(data,dtype=float).reshape(rows,width)
+ Z = Z[::-1,:]
+ imshow (Z, cmap=CM_Grey)
+
diff --git a/third_party/freetype-py/examples/example_1.py b/third_party/freetype-py/examples/example_1.py
new file mode 100644
index 0000000..a21512b
--- /dev/null
+++ b/third_party/freetype-py/examples/example_1.py
@@ -0,0 +1,89 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# -----------------------------------------------------------------------------
+#
+# FreeType high-level python API - Copyright 2011-2014 Nicolas P. Rougier
+# Distributed under the terms of the new BSD license.
+#
+# -----------------------------------------------------------------------------
+#
+# Direct translation of example 1 from the freetype tutorial:
+# http://www.freetype.org/freetype2/docs/tutorial/step1.html
+#
+import math
+from freetype import *
+
+
+if __name__ == '__main__':
+ from PIL import Image
+ from freetype import *
+
+ WIDTH, HEIGHT = 640, 480
+ image = Image.new('L', (WIDTH,HEIGHT))
+ def draw_bitmap( bitmap, x, y):
+ x_max = x + bitmap.width
+ y_max = y + bitmap.rows
+ p = 0
+ for p,i in enumerate(range(x,x_max)):
+ for q,j in enumerate(range(y,y_max)):
+ if i < 0 or j < 0 or i >= WIDTH or j >= HEIGHT:
+ continue;
+ pixel = image.getpixel((i,j))
+ pixel |= int(bitmap.buffer[q * bitmap.width + p]);
+ image.putpixel((i,j), pixel)
+
+ library = FT_Library()
+ matrix = FT_Matrix()
+ face = FT_Face()
+ pen = FT_Vector()
+ filename= './Vera.ttf'
+ text = 'Hello World !'
+ num_chars = len(text)
+ angle = ( 25.0 / 360 ) * 3.14159 * 2
+
+ # initialize library, error handling omitted
+ error = FT_Init_FreeType( byref(library) )
+
+ # create face object, error handling omitted
+ error = FT_New_Face( library, filename, 0, byref(face) )
+
+ # set character size: 50pt at 100dpi, error handling omitted
+ error = FT_Set_Char_Size( face, 50 * 64, 0, 100, 0 )
+ slot = face.contents.glyph
+
+ # set up matrix
+ matrix.xx = (int)( math.cos( angle ) * 0x10000L )
+ matrix.xy = (int)(-math.sin( angle ) * 0x10000L )
+ matrix.yx = (int)( math.sin( angle ) * 0x10000L )
+ matrix.yy = (int)( math.cos( angle ) * 0x10000L )
+
+ # the pen position in 26.6 cartesian space coordinates; */
+ # start at (300,200) relative to the upper left corner */
+ pen.x = 200 * 64;
+ pen.y = ( HEIGHT - 300 ) * 64
+
+ for n in range(num_chars):
+ # set transformation
+ FT_Set_Transform( face, byref(matrix), byref(pen) )
+
+ # load glyph image into the slot (erase previous one)
+ charcode = ord(text[n])
+ index = FT_Get_Char_Index( face, charcode )
+ FT_Load_Glyph( face, index, FT_LOAD_RENDER )
+
+ # now, draw to our target surface (convert position)
+ draw_bitmap( slot.contents.bitmap,
+ slot.contents.bitmap_left,
+ HEIGHT - slot.contents.bitmap_top )
+
+ # increment pen position
+ pen.x += slot.contents.advance.x
+ pen.y += slot.contents.advance.y
+
+ FT_Done_Face(face)
+ FT_Done_FreeType(library)
+
+ import matplotlib.pyplot as plt
+ plt.imshow(image, origin='lower',
+ interpolation='nearest', cmap=plt.cm.gray)
+ plt.show()
diff --git a/third_party/freetype-py/examples/font-info.py b/third_party/freetype-py/examples/font-info.py
new file mode 100644
index 0000000..015ee94
--- /dev/null
+++ b/third_party/freetype-py/examples/font-info.py
@@ -0,0 +1,42 @@
+# -----------------------------------------------------------------------------
+#
+# FreeType high-level python API - Copyright 2011 Nicolas P. Rougier
+# Distributed under the terms of the new BSD license.
+#
+# -----------------------------------------------------------------------------
+from freetype import *
+
+if __name__ == '__main__':
+ import sys
+
+ if len(sys.argv) < 2:
+ print("Usage: %s font_filename" % sys.argv[0])
+ sys.exit()
+
+ face = Face(sys.argv[1])
+
+ print 'Family name: ', face.family_name
+ print 'Style name: ', face.style_name
+ print 'Charmaps: ', [charmap.encoding_name for charmap in face.charmaps]
+ print
+ print 'Face number: ', face.num_faces
+ print 'Glyph number: ', face.num_glyphs
+ print 'Available sizes: ', face.available_sizes
+ print
+ print 'units per em: ', face.units_per_EM
+ print 'ascender: ', face.ascender
+ print 'descender: ', face.descender
+ print 'height: ', face.height
+ print
+ print 'max_advance_width: ', face.max_advance_width
+ print 'max_advance_height: ', face.max_advance_height
+ print
+ print 'underline_position: ', face.underline_position
+ print 'underline_thickness:', face.underline_thickness
+ print
+ print 'Has horizontal: ', face.has_horizontal
+ print 'Has vertical: ', face.has_vertical
+ print 'Has kerning: ', face.has_kerning
+ print 'Is fixed width: ', face.is_fixed_width
+ print 'Is scalable: ', face.is_scalable
+ print
diff --git a/third_party/freetype-py/examples/ftdump.py b/third_party/freetype-py/examples/ftdump.py
new file mode 100644
index 0000000..13662aa
--- /dev/null
+++ b/third_party/freetype-py/examples/ftdump.py
@@ -0,0 +1,295 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# -----------------------------------------------------------------------------
+# FreeType high-level python API - Copyright 2011 Nicolas P. Rougier
+# Distributed under the terms of the new BSD license.
+# -----------------------------------------------------------------------------
+from __future__ import print_function
+from __future__ import division
+import sys
+from freetype import *
+
+verbose = 0
+debug = 0
+name_tables = 0
+
+def usage( execname ):
+ print( )
+ print( "ftdump: simple font dumper -- part of the FreeType project" )
+ print( "----------------------------------------------------------" )
+ print( "Usage: %s [options] fontname", execname )
+ print( )
+ print( " -n print SFNT name tables" )
+ print( " -v be verbose" )
+ print( )
+ sys.exit()
+
+
+def Print_Name( face ):
+ print( "font name entries" );
+ print( " family: %s" % face.family_name )
+ print( " style: %s" % face.style_name )
+ ps_name = face.postscript_name or "UNAVAILABLE"
+ print( " postscript: %s" % ps_name )
+
+
+def Print_Type( face ):
+
+ print( "font type entries" )
+
+ # module = &face->driver->root;
+ # printf( " FreeType driver: %s\n", module->clazz->module_name );
+
+ # Is it better to dump all sfnt tag names?
+ print( " sfnt wrapped: ",end="")
+ if face.is_sfnt: print( "yes")
+ else: print( "no")
+
+ # is scalable ?
+ print( " type: ", end="")
+ if face.is_scalable:
+ print( "scalable, ", end="")
+ if face.has_multiple_masters:
+ print( "multiple_masters, ", end="")
+ if face.has_fixed_sizes:
+ print( "fixed size",end="")
+ print()
+
+ # Direction
+ print( " direction: ", end="" )
+ if face.has_horizontal:
+ print( "horizontal, ", end="")
+ if face.has_vertical:
+ print( "vertical", end="")
+ print( )
+
+ # Fixed width
+ print( " fixed width: ", end="")
+ if face.is_fixed_width: print( "yes")
+ else: print( "no")
+
+ # Glyph names
+ print( " glyph names: ", end="")
+ if face.has_glyph_names: print( "yes")
+ else: print( "no")
+
+ if face.is_scalable:
+ print( " EM size: %d" % face.units_per_EM )
+ print( " global BBox: (%ld,%ld):(%ld,%ld)" %
+ (face.bbox.xMin, face.bbox.yMin,
+ face.bbox.xMax, face.bbox.yMax ))
+ print( " ascent: %d" % face.ascender )
+ print( " descent: %d" % face.descender )
+ print( " text height: %d" % face.height )
+
+
+def get_platform_id( platform_id ):
+ if platform_id == TT_PLATFORM_APPLE_UNICODE:
+ return "Apple (Unicode)"
+ elif platform_id == TT_PLATFORM_MACINTOSH:
+ return "Macintosh"
+ elif platform_id == TT_PLATFORM_ISO:
+ return "ISO (deprecated)"
+ elif platform_id == TT_PLATFORM_MICROSOFT:
+ return "Microsoft"
+ elif platform_id == TT_PLATFORM_CUSTOM:
+ return "custom"
+ elif platform_id == TT_PLATFORM_ADOBE:
+ return "Adobe"
+ else:
+ return "UNKNOWN"
+
+def get_name_id( name_id ):
+ if name_id == TT_NAME_ID_COPYRIGHT:
+ return "copyright"
+ elif name_id == TT_NAME_ID_FONT_FAMILY:
+ return "font family"
+ elif name_id == TT_NAME_ID_FONT_SUBFAMILY:
+ return "font subfamily"
+ elif name_id == TT_NAME_ID_UNIQUE_ID:
+ return "unique ID"
+ elif name_id == TT_NAME_ID_FULL_NAME:
+ return "full name"
+ elif name_id == TT_NAME_ID_VERSION_STRING:
+ return "version string"
+ elif name_id == TT_NAME_ID_PS_NAME:
+ return "PostScript name"
+ elif name_id == TT_NAME_ID_TRADEMARK:
+ return "trademark"
+
+ # the following values are from the OpenType spec
+ elif name_id == TT_NAME_ID_MANUFACTURER:
+ return "manufacturer"
+ elif name_id == TT_NAME_ID_DESIGNER:
+ return "designer"
+ elif name_id == TT_NAME_ID_DESCRIPTION:
+ return "description"
+ elif name_id == TT_NAME_ID_VENDOR_URL:
+ return "vendor URL"
+ elif name_id == TT_NAME_ID_DESIGNER_URL:
+ return "designer URL"
+ elif name_id == TT_NAME_ID_LICENSE:
+ return "license"
+ elif name_id == TT_NAME_ID_LICENSE_URL:
+ return "license URL"
+ # number 15 is reserved
+ elif name_id == TT_NAME_ID_PREFERRED_FAMILY:
+ return "preferred family"
+ elif name_id == TT_NAME_ID_PREFERRED_SUBFAMILY:
+ return "preferred subfamily"
+ elif name_id == TT_NAME_ID_MAC_FULL_NAME:
+ return "Mac full name"
+
+ # The following code is new as of 2000-01-21
+ elif name_id == TT_NAME_ID_SAMPLE_TEXT:
+ return "sample text"
+
+ # This is new in OpenType 1.3
+ elif name_id == TT_NAME_ID_CID_FINDFONT_NAME:
+ return "CID 'findfont' name"
+ else:
+ return "UNKNOWN";
+
+
+def Print_Sfnt_Names( face ):
+ print( "font string entries" );
+
+ for i in range(face.sfnt_name_count):
+
+ name = face.get_sfnt_name(i)
+ print( " %-15s [%s]" % ( get_name_id( name.name_id ),
+ get_platform_id( name.platform_id )),end="")
+
+ if name.platform_id == TT_PLATFORM_APPLE_UNICODE:
+ if name.encoding_id in [TT_APPLE_ID_DEFAULT,
+ TT_APPLE_ID_UNICODE_1_1,
+ TT_APPLE_ID_ISO_10646,
+ TT_APPLE_ID_UNICODE_2_0]:
+ print(name.string.decode('utf-16be', 'ignore'))
+ else:
+ print( "{unsupported encoding %d}" % name.encoding_id )
+
+ elif name.platform_id == TT_PLATFORM_MACINTOSH:
+ if name.language_id != TT_MAC_LANGID_ENGLISH:
+ print( " (language=%d)" % name.language_id )
+ print ( " : " )
+ if name.encoding_id == TT_MAC_ID_ROMAN:
+ # FIXME: convert from MacRoman to ASCII/ISO8895-1/whatever
+ # (MacRoman is mostly like ISO8895-1 but there are differences)
+ print(name.string)
+ else:
+ print( "{unsupported encoding %d}" % name.encoding_id )
+
+ elif name.platform_id == TT_PLATFORM_ISO:
+ if name.encoding_id in [ TT_ISO_ID_7BIT_ASCII,
+ TT_ISO_ID_8859_1]:
+ print(name.string)
+ print ( " : " )
+ if name.encoding_id == TT_ISO_ID_10646:
+ print(name.string.decode('utf-16be', 'ignore'))
+ else:
+ print( "{unsupported encoding %d}" % name.encoding_id )
+
+ elif name.platform_id == TT_PLATFORM_MICROSOFT:
+ if name.language_id != TT_MS_LANGID_ENGLISH_UNITED_STATES:
+ print( " (language=0x%04x)" % name.language_id );
+ print( " : " )
+ if name.encoding_id in [TT_MS_ID_SYMBOL_CS,
+ TT_MS_ID_UNICODE_CS]:
+ print(name.string.decode('utf-16be', 'ignore'))
+ else:
+ print( "{unsupported encoding %d}" % name.encoding_id )
+ else:
+ print( "{unsupported platform}" )
+
+ print( )
+
+
+def Print_Fixed( face ):
+
+ # num_fixed_size
+ print( "fixed size\n" )
+
+ # available size
+ for i,bsize in enumerate(face.available_sizes):
+ print( " %3d: height %d, width %d\n",
+ i, bsize.height, bsize.width )
+ print( " size %.3f, x_ppem %.3f, y_ppem %.3f\n",
+ bsize.size / 64.0,
+ bsize.x_ppem / 64.0, bsize.y_ppem / 64.0 )
+
+
+def Print_Charmaps( face ):
+ global verbose
+ active = -1
+ if face.charmap:
+ active = face.charmap.index
+
+ # CharMaps
+ print( "charmaps" )
+ for i,charmap in enumerate(face.charmaps):
+ print( " %d: platform %d, encoding %d, language %d" %
+ (i, charmap.platform_id, charmap.encoding_id,
+ int(charmap.cmap_language_id)), end="" )
+ if i == active:
+ print( " (active)", end="" )
+ print ( )
+ if verbose:
+ face.set_charmap( charmap )
+ charcode, gindex = face.get_first_char()
+ while ( gindex ):
+ print( " 0x%04lx => %d" % (charcode, gindex) )
+ charcode, gindex = face.get_next_char( charcode, gindex )
+
+
+
+# -----------------------------------------------------------------------------
+if __name__ == '__main__':
+ import getopt
+ execname = sys.argv[0]
+
+ if len(sys.argv) < 2:
+ usage( execname )
+
+ try:
+ opts, args = getopt.getopt(sys.argv[1:], ':nv')
+ except getopt.GetoptError, err:
+ usage( execname )
+
+ verbose = False
+ name_tables = False
+
+ for o, a in opts:
+ if o == "-v": verbose = True
+ elif o == "-n": name_tables = True
+ else: usage( execname )
+
+
+ face = Face(args[0])
+ num_faces = face.num_faces
+
+ if num_faces > 1:
+ print( "There are %d faces in this file." % num_faces)
+ else:
+ print( "There is 1 face in this file.")
+
+ for i in range(num_faces):
+ face = Face(args[0], i)
+
+ print( "\n----- Face number: %d -----\n" % i )
+ Print_Name( face )
+ print( "" )
+ Print_Type( face )
+ print( " glyph count: %d" % face.num_glyphs )
+
+ if name_tables and face.is_sfnt:
+ print( )
+ Print_Sfnt_Names( face )
+
+ if face.num_fixed_sizes:
+ print( )
+ Print_Fixed( face )
+
+ if face.num_charmaps:
+ print( )
+ Print_Charmaps( face )
diff --git a/third_party/freetype-py/examples/glyph-alpha.py b/third_party/freetype-py/examples/glyph-alpha.py
new file mode 100644
index 0000000..2477450
--- /dev/null
+++ b/third_party/freetype-py/examples/glyph-alpha.py
@@ -0,0 +1,31 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# -----------------------------------------------------------------------------
+#
+# FreeType high-level python API - Copyright 2011 Nicolas P. Rougier
+# Distributed under the terms of the new BSD license.
+#
+# -----------------------------------------------------------------------------
+'''
+Glyph bitmap monochrome rendering
+'''
+from freetype import *
+
+if __name__ == '__main__':
+ import numpy
+ import matplotlib.pyplot as plt
+
+ face = Face('./Vera.ttf')
+ face.set_char_size( 48*64 )
+ face.load_char('S', FT_LOAD_RENDER )
+ bitmap = face.glyph.bitmap
+ width = face.glyph.bitmap.width
+ rows = face.glyph.bitmap.rows
+ pitch = face.glyph.bitmap.pitch
+
+ data = []
+ for i in range(rows):
+ data.extend(bitmap.buffer[i*pitch:i*pitch+width])
+ Z = numpy.array(data,dtype=numpy.ubyte).reshape(rows, width)
+ plt.imshow(Z, interpolation='nearest', cmap=plt.cm.gray, origin='lower')
+ plt.show()
diff --git a/third_party/freetype-py/examples/glyph-color.py b/third_party/freetype-py/examples/glyph-color.py
new file mode 100644
index 0000000..7f3b28e
--- /dev/null
+++ b/third_party/freetype-py/examples/glyph-color.py
@@ -0,0 +1,94 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# -----------------------------------------------------------------------------
+#
+# FreeType high-level python API - Copyright 2011 Nicolas P. Rougier
+# Distributed under the terms of the new BSD license.
+#
+# -----------------------------------------------------------------------------
+'''
+Glyph colored rendering (with outline)
+'''
+from freetype import *
+
+if __name__ == '__main__':
+ import numpy as np
+ import matplotlib.pyplot as plt
+
+ face = Face('./Vera.ttf')
+ face.set_char_size( 96*64 )
+ RGBA = [('R',float), ('G',float), ('B',float), ('A',float)]
+
+ # Outline
+ flags = FT_LOAD_DEFAULT | FT_LOAD_NO_BITMAP
+ face.load_char('S', flags )
+ slot = face.glyph
+ glyph = slot.get_glyph()
+ stroker = Stroker( )
+ stroker.set(64, FT_STROKER_LINECAP_ROUND, FT_STROKER_LINEJOIN_ROUND, 0 )
+ glyph.stroke( stroker )
+ blyph = glyph.to_bitmap(FT_RENDER_MODE_NORMAL, Vector(0,0))
+ bitmap = blyph.bitmap
+ width, rows, pitch = bitmap.width, bitmap.rows, bitmap.pitch
+ top, left = blyph.top, blyph.left
+ data = []
+ for i in range(rows):
+ data.extend(bitmap.buffer[i*pitch:i*pitch+width])
+ Z = np.array(data).reshape(rows, width)/255.0
+ O = np.zeros((rows,width), dtype=RGBA)
+ O['A'] = Z
+ O['R'] = 1
+ O['G'] = 0
+ O['B'] = 0
+
+ # Plain
+ flags = FT_LOAD_RENDER
+ face.load_char('S', flags)
+ F = np.zeros((rows,width), dtype=RGBA)
+ Z = np.zeros((rows, width))
+ bitmap = face.glyph.bitmap
+ width, rows, pitch = bitmap.width, bitmap.rows, bitmap.pitch
+ top, left = face.glyph.bitmap_top, face.glyph.bitmap_left
+ dy = blyph.top - face.glyph.bitmap_top
+ dx = face.glyph.bitmap_left - blyph.left
+ data = []
+ for i in range(rows):
+ data.extend(bitmap.buffer[i*pitch:i*pitch+width])
+ Z[dx:dx+rows,dy:dy+width] = np.array(data).reshape(rows, width)/255.
+ F['R'] = 1
+ F['G'] = 1
+ F['B'] = 0
+ F['A'] = Z
+
+ # Combine outline and plain
+ R1,G1,B1,A1 = O['R'],O['G'],O['B'],O['A']
+ R2,G2,B2,A2 = F['R'],F['G'],F['B'],F['A']
+ Z = np.zeros(O.shape, dtype=RGBA)
+ Z['R'] = (A1 * R1 + A2 * (1 - A1) * R2)
+ Z['G'] = (A1 * G1 + A2 * (1 - A1) * G2)
+ Z['B'] = (A1 * B1 + A2 * (1 - A1) * B2)
+ Z['A'] = (A1 + A2 * (1 - A1))
+
+
+ # Draw
+ plt.figure(figsize=(12,5))
+
+ plt.subplot(1,3,1)
+ plt.title('Plain')
+ plt.xticks([]), plt.yticks([])
+ I = F.view(dtype=float).reshape(O.shape[0],O.shape[1],4)
+ plt.imshow(I, interpolation='nearest', origin='lower')
+
+ plt.subplot(1,3,2)
+ plt.title('Outline')
+ plt.xticks([]), plt.yticks([])
+ I = O.view(dtype=float).reshape(O.shape[0],O.shape[1],4)
+ plt.imshow(I, interpolation='nearest', origin='lower')
+
+ plt.subplot(1,3,3)
+ plt.title('Outline + Plain')
+ plt.xticks([]), plt.yticks([])
+ I = Z.view(dtype=float).reshape(O.shape[0],O.shape[1],4)
+ plt.imshow(I, interpolation='nearest', origin='lower')
+
+ plt.show()
diff --git a/third_party/freetype-py/examples/glyph-lcd.py b/third_party/freetype-py/examples/glyph-lcd.py
new file mode 100644
index 0000000..5992c12
--- /dev/null
+++ b/third_party/freetype-py/examples/glyph-lcd.py
@@ -0,0 +1,32 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# -----------------------------------------------------------------------------
+#
+# FreeType high-level python API - Copyright 2011 Nicolas P. Rougier
+# Distributed under the terms of the new BSD license.
+#
+# -----------------------------------------------------------------------------
+'''
+Glyph bitmap monochrome rendring
+'''
+from freetype import *
+
+if __name__ == '__main__':
+ import numpy
+ import matplotlib.pyplot as plt
+
+ face = Face('./Vera.ttf')
+ face.set_char_size( 48*64 )
+ face.load_char('S', FT_LOAD_RENDER |
+ FT_LOAD_TARGET_LCD )
+ bitmap = face.glyph.bitmap
+ width = face.glyph.bitmap.width
+ rows = face.glyph.bitmap.rows
+ pitch = face.glyph.bitmap.pitch
+
+ data = []
+ for i in range(rows):
+ data.extend(bitmap.buffer[i*pitch:i*pitch+width])
+ Z = numpy.array(data,dtype=numpy.ubyte).reshape(rows, width/3, 3)
+ plt.imshow(Z, interpolation='nearest', origin='lower')
+ plt.show()
diff --git a/third_party/freetype-py/examples/glyph-metrics.py b/third_party/freetype-py/examples/glyph-metrics.py
new file mode 100644
index 0000000..f0bb21a
--- /dev/null
+++ b/third_party/freetype-py/examples/glyph-metrics.py
@@ -0,0 +1,233 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# -----------------------------------------------------------------------------
+#
+# FreeType high-level python API - Copyright 2011 Nicolas P. Rougier
+# Distributed under the terms of the new BSD license.
+#
+# -----------------------------------------------------------------------------
+'''
+Show glyph metrics in horizontal and vertical layout
+'''
+from freetype import *
+
+def arrow( x,y, dx, dy, **kwargs):
+ kwargs['shape'] = 'full'
+ kwargs['head_width'] = 30
+ kwargs['head_length'] = 40
+ kwargs['length_includes_head'] =True
+ kwargs['facecolor'] = 'k'
+ kwargs['edgecolor'] ='k'
+ kwargs['linewidth'] =.5
+ plt.arrow(x,y,dx,dy,**kwargs)
+
+def double_arrow(x, y, dx, dy, **kwargs):
+ cx,cy = x+dx/2., y+dy/2.
+ dx /= 2.0
+ dy /= 2.0
+ arrow(cx,cy,+dx,+dy,**kwargs)
+ arrow(cx,cy,-dx,-dy,**kwargs)
+
+def line(x, y, dx, dy, **kwargs):
+ kwargs['color'] = 'k'
+ kwargs['linewidth'] =.5
+ plt.plot([x,x+dx],[y,y+dy],**kwargs)
+
+def point(x, y, r, **kwargs):
+ kwargs['color'] = 'k'
+ plt.scatter([x],[y],r,**kwargs)
+
+def text( x,y,text, **kwargs):
+ kwargs['fontsize'] = 18
+ plt.text(x, y, text, **kwargs)
+
+
+
+if __name__ == '__main__':
+ import numpy as np
+ import matplotlib.pyplot as plt
+ from matplotlib.path import Path
+ import matplotlib.patches as patches
+
+
+ face = Face('./Vera.ttf')
+ face.set_char_size( 32*64 )
+ face.load_char('g')
+ slot = face.glyph
+ bitmap = slot.bitmap
+ width = slot.bitmap.width
+ rows = slot.bitmap.rows
+ pitch = slot.bitmap.pitch
+ outline= slot.outline
+
+ start, end = 0, 0
+ VERTS, CODES = [], []
+ # Iterate over each contour
+ for i in range(len(outline.contours)):
+ end = outline.contours[i]
+ points = outline.points[start:end+1]
+ points.append(points[0])
+ tags = outline.tags[start:end+1]
+ tags.append(tags[0])
+ segments = [ [points[0],], ]
+ for j in range(1, len(points) ):
+ segments[-1].append(points[j])
+ if tags[j] & (1 << 0) and j < (len(points)-1):
+ segments.append( [points[j],] )
+ verts = [points[0], ]
+ codes = [Path.MOVETO,]
+ for segment in segments:
+ if len(segment) == 2:
+ verts.extend(segment[1:])
+ codes.extend([Path.LINETO])
+ elif len(segment) == 3:
+ verts.extend(segment[1:])
+ codes.extend([Path.CURVE3, Path.CURVE3])
+ else:
+ verts.append(segment[1])
+ codes.append(Path.CURVE3)
+ for i in range(1,len(segment)-2):
+ A,B = segment[i], segment[i+1]
+ C = ((A[0]+B[0])/2.0, (A[1]+B[1])/2.0)
+ verts.extend([ C, B ])
+ codes.extend([ Path.CURVE3, Path.CURVE3])
+ verts.append(segment[-1])
+ codes.append(Path.CURVE3)
+ VERTS.extend(verts)
+ CODES.extend(codes)
+ start = end+1
+ VERTS = np.array(VERTS)
+ x,y = VERTS[:,0], VERTS[:,1]
+ VERTS[:,0], VERTS[:,1] = x, y
+
+
+ path = Path(VERTS, CODES)
+ xmin, xmax = x.min(), x.max()
+ ymin, ymax = y.min(), y.max()
+ width,height = xmax-xmin, ymax-ymin
+ dw, dh = 0.2*width, 0.1*height
+ bearing = xmin - slot.metrics.horiBearingX, ymin - slot.metrics.horiBearingY
+ advance = slot.advance
+ origin = bearing
+
+
+ figure = plt.figure(figsize=(16,10), frameon=False, facecolor="white")
+
+ axes = plt.subplot(121, frameon=False, aspect=1)
+ glyph = patches.PathPatch(path, fill = True, facecolor='k', lw=0)
+ plt.xlim(xmin - .25*width, xmax + .75*width)
+ plt.ylim(ymin - .5*height, xmax + .75*height)
+ plt.xticks([]), plt.yticks([])
+ axes.add_patch(glyph)
+
+ # Y axis
+ arrow(origin[0], ymin-dh, 0, height+3*dh)
+
+ # X axis
+ arrow(origin[0]-dw, 0, width+3*dw, 0)
+
+ # origin
+ point(0,0,50)
+ text( -20, -20, "$origin$", va='top', ha='right')
+
+ # Bounding box
+ bbox = patches.Rectangle( (xmin,ymin), width, height, fill = False, lw=.5)
+ axes.add_patch(bbox)
+
+ # Width
+ line(xmin, ymax, 0, 3*dh, linestyle="dotted")
+ text( xmin, ymax+3.25*dh, "$x_{min}$", va='bottom', ha='center')
+ line(xmax, ymax, 0, 3*dh, linestyle="dotted")
+ text( xmax, ymax+3.25*dh, "$x_{max}$", va='bottom', ha='center')
+ double_arrow(xmin, ymax+2.5*dh, width, 0)
+ text(xmin+width/2., ymax+1.75*dh, "$width$", va='bottom', ha='center')
+
+ # Height
+ line(xmax, ymin, 3*dw, 0, linestyle="dotted")
+ text(xmax+3.25*dw, ymin, "$y_{min}$", va='baseline', ha='left')
+ line(xmax, ymax, 3*dw, 0, linestyle="dotted")
+ text(xmax+3.25*dw, ymax, "$y_{max}$", va='baseline', ha='left')
+ double_arrow(xmax+2.5*dw, ymin, 0, height)
+ text(xmax+2.75*dw, ymin+height/2., "$height$", va='center', ha='left')
+
+ # Advance
+ point(advance.x,0,50)
+ line(advance.x, 0, 0, ymin-dh, linestyle="dotted")
+ arrow(0, ymin-.5*dh, advance.x, 0)
+ text(advance.x/2., ymin-1.25*dh, "$advance$", va='bottom', ha='center')
+
+ # Bearing Y
+ arrow(xmax+.25*dw, 0, 0, ymax)
+ text(xmax+.5*dw, ymax/2, "$Y_{bearing}$", va='center', ha='left')
+
+ # Bearing X
+ arrow(0, ymax/2., xmin, 0)
+ text(-10, ymax/2, "$X_{bearing}$", va='baseline', ha='right')
+
+
+ # -------------------------------------------------------------------------
+
+ axes = plt.subplot(122, frameon=False, aspect=1)
+ glyph = patches.PathPatch(path, fill = True, facecolor='k', lw=0)
+ axes.add_patch(glyph)
+
+ plt.xlim(xmin - .25*width, xmax + .75*width)
+ plt.ylim(ymin - .5*height, xmax + .75*height)
+ plt.xticks([]), plt.yticks([])
+
+
+ advance = slot.metrics.vertAdvance
+ x_bearing = slot.metrics.vertBearingX
+ y_bearing = slot.metrics.vertBearingY
+
+ # Y axis
+ arrow(xmin-x_bearing, ymax+y_bearing+2*dh, 0, -advance-3*dh)
+
+ # X axis
+ arrow(xmin-2*dw, ymax+y_bearing, width+4*dw, 0)
+
+ # origin
+ point( xmin-x_bearing, ymax+y_bearing, 50)
+ text( xmin-x_bearing-30, ymax+y_bearing+10, "$origin$", va='bottom', ha='right')
+
+ # Bounding box
+ bbox = patches.Rectangle( (xmin,ymin), width, height, fill = False, lw=.5)
+ axes.add_patch(bbox)
+
+
+ # # Advance
+ point(xmin-x_bearing, ymax+y_bearing-advance, 50)
+ line(xmin-x_bearing, ymax+y_bearing-advance, xmax-dw, 0, linestyle="dotted")
+ arrow(xmax+dw, ymax+y_bearing, 0, -advance)
+ text(xmax+1.25*dw, ymax+y_bearing-advance/2., "$advance$", va='baseline', ha='left')
+
+
+ # Width
+ line(xmin, ymin, 0, -4*dh, linestyle="dotted")
+ text( xmin, ymin-4.25*dh, "$x_{min}$", va='top', ha='center')
+ line(xmax, ymin, 0, -4*dh, linestyle="dotted")
+ text( xmax, ymin-4.25*dh, "$x_{max}$", va='top', ha='center')
+ double_arrow(xmin, ymin-3.5*dh, width, 0)
+ text(xmin+width/2., ymin-3.75*dh, "$width$", va='top', ha='center')
+
+ # Height
+ line(xmin, ymin, -3*dw, 0, linestyle="dotted")
+ text(xmin-1.5*dw, ymin, "$y_{min}$", va='baseline', ha='right')
+ line(xmin, ymax, -3*dw, 0, linestyle="dotted")
+ text(xmin-1.5*dw, ymax, "$y_{max}$", va='baseline', ha='right')
+ double_arrow(xmin-.5*dw, ymin, 0, height)
+ text(xmin-.75*dw, ymin+height/2., "$height$", va='center', ha='right')
+
+
+ #point(xmin-x_bearing, ymax+y_bearing, 50)
+ # Bearing Y
+ arrow(xmax-.5*dw, ymax+y_bearing, 0, -y_bearing)
+ text(xmax-.5*dw, ymax+y_bearing+.25*dh, "$Y_{bearing}$", va='bottom', ha='center')
+
+ # # Bearing X
+ line(xmin, ymax, 0, 3*dh, linestyle="dotted")
+ arrow(xmin-x_bearing, ymax+y_bearing+dh, x_bearing, 0)
+ text(xmin-.25*dw, ymax+y_bearing+dh, "$X_{bearing}$", va='baseline', ha='right')
+
+ plt.savefig('glyph-metrics.pdf')
+ plt.show()
diff --git a/third_party/freetype-py/examples/glyph-monochrome.py b/third_party/freetype-py/examples/glyph-monochrome.py
new file mode 100644
index 0000000..3714ceb
--- /dev/null
+++ b/third_party/freetype-py/examples/glyph-monochrome.py
@@ -0,0 +1,43 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# -----------------------------------------------------------------------------
+#
+# FreeType high-level python API - Copyright 2011 Nicolas P. Rougier
+# Distributed under the terms of the new BSD license.
+#
+# -----------------------------------------------------------------------------
+'''
+Glyph bitmap monochrome rendring
+'''
+from freetype import *
+
+def bits(x):
+ data = []
+ for i in range(8):
+ data.insert(0, int((x & 1) == 1))
+ x = x >> 1
+ return data
+
+if __name__ == '__main__':
+ import numpy
+ import matplotlib.pyplot as plt
+
+ face = Face('./Vera.ttf')
+ face.set_char_size( 48*64 )
+ face.load_char('S', FT_LOAD_RENDER |
+ FT_LOAD_TARGET_MONO )
+
+ bitmap = face.glyph.bitmap
+ width = face.glyph.bitmap.width
+ rows = face.glyph.bitmap.rows
+ pitch = face.glyph.bitmap.pitch
+
+ data = []
+ for i in range(bitmap.rows):
+ row = []
+ for j in range(bitmap.pitch):
+ row.extend(bits(bitmap.buffer[i*bitmap.pitch+j]))
+ data.extend(row[:bitmap.width])
+ Z = numpy.array(data).reshape(bitmap.rows, bitmap.width)
+ plt.imshow(Z, interpolation='nearest', cmap=plt.cm.gray, origin='lower')
+ plt.show()
diff --git a/third_party/freetype-py/examples/glyph-outline.py b/third_party/freetype-py/examples/glyph-outline.py
new file mode 100644
index 0000000..6588e21
--- /dev/null
+++ b/third_party/freetype-py/examples/glyph-outline.py
@@ -0,0 +1,37 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# -----------------------------------------------------------------------------
+#
+# FreeType high-level python API - Copyright 2011 Nicolas P. Rougier
+# Distributed under the terms of the new BSD license.
+#
+# -----------------------------------------------------------------------------
+'''
+Glyph outline rendering
+'''
+from freetype import *
+
+if __name__ == '__main__':
+ import numpy
+ import matplotlib.pyplot as plt
+
+ face = Face('./Vera.ttf')
+ face.set_char_size( 4*48*64 )
+ flags = FT_LOAD_DEFAULT | FT_LOAD_NO_BITMAP
+ face.load_char('S', flags )
+ slot = face.glyph
+ glyph = slot.get_glyph()
+ stroker = Stroker( )
+ stroker.set(64, FT_STROKER_LINECAP_ROUND, FT_STROKER_LINEJOIN_ROUND, 0 )
+ glyph.stroke( stroker )
+ blyph = glyph.to_bitmap(FT_RENDER_MODE_NORMAL, Vector(0,0))
+ bitmap = blyph.bitmap
+ width, rows, pitch = bitmap.width, bitmap.rows, bitmap.pitch
+ top, left = blyph.top, blyph.left
+ data = []
+ for i in range(rows):
+ data.extend(bitmap.buffer[i*pitch:i*pitch+width])
+ Z = numpy.array(data,dtype=numpy.ubyte).reshape(rows, width)
+ plt.figure(figsize=(6,8))
+ plt.imshow(Z, interpolation='nearest', cmap=plt.cm.gray_r, origin='lower')
+ plt.show()
diff --git a/third_party/freetype-py/examples/glyph-vector-2.py b/third_party/freetype-py/examples/glyph-vector-2.py
new file mode 100644
index 0000000..fc2c7da
--- /dev/null
+++ b/third_party/freetype-py/examples/glyph-vector-2.py
@@ -0,0 +1,98 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# -----------------------------------------------------------------------------
+#
+# FreeType high-level python API - Copyright 2011 Nicolas P. Rougier
+# Distributed under the terms of the new BSD license.
+#
+# -----------------------------------------------------------------------------
+'''
+Show how to access glyph outline description.
+'''
+from freetype import *
+
+if __name__ == '__main__':
+ import numpy
+ import matplotlib.pyplot as plt
+ from matplotlib.path import Path
+ import matplotlib.patches as patches
+
+ face = Face('./Vera.ttf')
+ face.set_char_size( 32*64 )
+ face.load_char('g')
+ slot = face.glyph
+
+ bitmap = face.glyph.bitmap
+ width = face.glyph.bitmap.width
+ rows = face.glyph.bitmap.rows
+ pitch = face.glyph.bitmap.pitch
+
+ data = []
+ for i in range(rows):
+ data.extend(bitmap.buffer[i*pitch:i*pitch+width])
+ Z = numpy.array(data,dtype=numpy.ubyte).reshape(rows, width)
+
+ outline = slot.outline
+ points = numpy.array(outline.points, dtype=[('x',float), ('y',float)])
+ x, y = points['x'], points['y']
+
+ figure = plt.figure(figsize=(8,10))
+ axis = figure.add_subplot(111)
+ #axis.scatter(points['x'], points['y'], alpha=.25)
+ start, end = 0, 0
+
+ VERTS, CODES = [], []
+ # Iterate over each contour
+ for i in range(len(outline.contours)):
+ end = outline.contours[i]
+ points = outline.points[start:end+1]
+ points.append(points[0])
+ tags = outline.tags[start:end+1]
+ tags.append(tags[0])
+
+ segments = [ [points[0],], ]
+ for j in range(1, len(points) ):
+ segments[-1].append(points[j])
+ if tags[j] & (1 << 0) and j < (len(points)-1):
+ segments.append( [points[j],] )
+ verts = [points[0], ]
+ codes = [Path.MOVETO,]
+ for segment in segments:
+ if len(segment) == 2:
+ verts.extend(segment[1:])
+ codes.extend([Path.LINETO])
+ elif len(segment) == 3:
+ verts.extend(segment[1:])
+ codes.extend([Path.CURVE3, Path.CURVE3])
+ else:
+ verts.append(segment[1])
+ codes.append(Path.CURVE3)
+ for i in range(1,len(segment)-2):
+ A,B = segment[i], segment[i+1]
+ C = ((A[0]+B[0])/2.0, (A[1]+B[1])/2.0)
+ verts.extend([ C, B ])
+ codes.extend([ Path.CURVE3, Path.CURVE3])
+ verts.append(segment[-1])
+ codes.append(Path.CURVE3)
+ VERTS.extend(verts)
+ CODES.extend(codes)
+ start = end+1
+
+
+ # Draw glyph
+ path = Path(VERTS, CODES)
+ glyph = patches.PathPatch(path, fill = True, facecolor=(0.8,0.5,0.8), alpha=.25, lw=0)
+ glyph_outline = patches.PathPatch(path, fill = False, edgecolor='black', lw=3)
+
+ plt.imshow(Z, extent=[x.min(), x.max(),y.min(), y.max()], origin='lower',
+ interpolation='nearest', cmap = plt.cm.gray_r, vmin=0, vmax=400)
+ plt.xticks(numpy.linspace(x.min(), x.max(), Z.shape[1]+1), ())
+ plt.yticks(numpy.linspace(y.min(), y.max(), Z.shape[0]+1), ())
+ plt.grid(color='k', linewidth=1, linestyle='-')
+ axis.add_patch(glyph)
+ axis.add_patch(glyph_outline)
+ axis.set_xlim(x.min(), x.max())
+ axis.set_ylim(y.min(), y.max())
+
+ plt.savefig('test.svg')
+ plt.show()
diff --git a/third_party/freetype-py/examples/glyph-vector.py b/third_party/freetype-py/examples/glyph-vector.py
new file mode 100644
index 0000000..8cc34bf
--- /dev/null
+++ b/third_party/freetype-py/examples/glyph-vector.py
@@ -0,0 +1,91 @@
+# -----------------------------------------------------------------------------
+#
+# FreeType high-level python API - Copyright 2011 Nicolas P. Rougier
+# Distributed under the terms of the new BSD license.
+#
+# -----------------------------------------------------------------------------
+'''
+Show how to access glyph outline description.
+'''
+from freetype import *
+
+if __name__ == '__main__':
+ import numpy
+ import matplotlib.pyplot as plt
+ from matplotlib.path import Path
+ import matplotlib.patches as patches
+
+ face = Face('./Vera.ttf')
+ face.set_char_size( 48*64 )
+ face.load_char('S')
+ slot = face.glyph
+
+ outline = slot.outline
+ points = numpy.array(outline.points, dtype=[('x',float), ('y',float)])
+ x, y = points['x'], points['y']
+
+ figure = plt.figure(figsize=(8,10))
+ axis = figure.add_subplot(111)
+ #axis.scatter(points['x'], points['y'], alpha=.25)
+ start, end = 0, 0
+
+ VERTS, CODES = [], []
+ # Iterate over each contour
+ for i in range(len(outline.contours)):
+ end = outline.contours[i]
+ points = outline.points[start:end+1]
+ points.append(points[0])
+ tags = outline.tags[start:end+1]
+ tags.append(tags[0])
+
+ segments = [ [points[0],], ]
+ for j in range(1, len(points) ):
+ segments[-1].append(points[j])
+ if tags[j] & (1 << 0) and j < (len(points)-1):
+ segments.append( [points[j],] )
+ verts = [points[0], ]
+ codes = [Path.MOVETO,]
+ for segment in segments:
+ if len(segment) == 2:
+ verts.extend(segment[1:])
+ codes.extend([Path.LINETO])
+ elif len(segment) == 3:
+ verts.extend(segment[1:])
+ codes.extend([Path.CURVE3, Path.CURVE3])
+ else:
+ verts.append(segment[1])
+ codes.append(Path.CURVE3)
+ for i in range(1,len(segment)-2):
+ A,B = segment[i], segment[i+1]
+ C = ((A[0]+B[0])/2.0, (A[1]+B[1])/2.0)
+ verts.extend([ C, B ])
+ codes.extend([ Path.CURVE3, Path.CURVE3])
+ verts.append(segment[-1])
+ codes.append(Path.CURVE3)
+ VERTS.extend(verts)
+ CODES.extend(codes)
+ start = end+1
+
+
+ # Draw glyph lines
+ path = Path(VERTS, CODES)
+ glyph = patches.PathPatch(path, facecolor='.75', lw=1)
+
+ # Draw "control" lines
+ for i, code in enumerate(CODES):
+ if code == Path.CURVE3:
+ CODES[i] = Path.LINETO
+ path = Path(VERTS, CODES)
+ patch = patches.PathPatch(path, ec='.5', fill=False, ls='dashed', lw=1 )
+
+ axis.add_patch(patch)
+ axis.add_patch(glyph)
+
+ axis.set_xlim(x.min()-100, x.max()+100)
+ plt.xticks([])
+ axis.set_ylim(y.min()-100, y.max()+100)
+ plt.yticks([])
+ plt.show()
+
+
+
diff --git a/third_party/freetype-py/examples/hello-world.py b/third_party/freetype-py/examples/hello-world.py
new file mode 100644
index 0000000..72126ae
--- /dev/null
+++ b/third_party/freetype-py/examples/hello-world.py
@@ -0,0 +1,54 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# -----------------------------------------------------------------------------
+#
+# FreeType high-level python API - Copyright 2011 Nicolas P. Rougier
+# Distributed under the terms of the new BSD license.
+#
+# -----------------------------------------------------------------------------
+from freetype import *
+
+if __name__ == '__main__':
+ import numpy
+ import matplotlib.pyplot as plt
+
+ face = Face('./Vera.ttf')
+ text = 'Hello World !'
+ face.set_char_size( 48*64 )
+ slot = face.glyph
+
+ # First pass to compute bbox
+ width, height, baseline = 0, 0, 0
+ previous = 0
+ for i,c in enumerate(text):
+ face.load_char(c)
+ bitmap = slot.bitmap
+ height = max(height,
+ bitmap.rows + max(0,-(slot.bitmap_top-bitmap.rows)))
+ baseline = max(baseline, max(0,-(slot.bitmap_top-bitmap.rows)))
+ kerning = face.get_kerning(previous, c)
+ width += (slot.advance.x >> 6) + (kerning.x >> 6)
+ previous = c
+
+ Z = numpy.zeros((height,width), dtype=numpy.ubyte)
+
+ # Second pass for actual rendering
+ x, y = 0, 0
+ previous = 0
+ for c in text:
+ face.load_char(c)
+ bitmap = slot.bitmap
+ top = slot.bitmap_top
+ left = slot.bitmap_left
+ w,h = bitmap.width, bitmap.rows
+ y = height-baseline-top
+ kerning = face.get_kerning(previous, c)
+ x += (kerning.x >> 6)
+ Z[y:y+h,x:x+w] += numpy.array(bitmap.buffer).reshape(h,w)
+ x += (slot.advance.x >> 6)
+ previous = c
+
+ plt.figure(figsize=(10, 10*Z.shape[0]/float(Z.shape[1])))
+ plt.imshow(Z, interpolation='nearest', origin='upper', cmap=plt.cm.gray)
+ plt.xticks([]), plt.yticks([])
+ plt.show()
diff --git a/third_party/freetype-py/examples/opengl.py b/third_party/freetype-py/examples/opengl.py
new file mode 100644
index 0000000..19309be
--- /dev/null
+++ b/third_party/freetype-py/examples/opengl.py
@@ -0,0 +1,122 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# -----------------------------------------------------------------------------
+#
+# FreeType high-level python API - Copyright 2011 Nicolas P. Rougier
+# Distributed under the terms of the new BSD license.
+#
+# -----------------------------------------------------------------------------
+import numpy
+from freetype import *
+import OpenGL.GL as gl
+import OpenGL.GLUT as glut
+
+base, texid = 0, 0
+text = '''Hello World !'''
+
+def on_display( ):
+ global texid
+ gl.glClearColor(1,1,1,1)
+ gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT)
+ gl.glBindTexture( gl.GL_TEXTURE_2D, texid )
+ gl.glColor(0,0,0,1)
+ gl.glPushMatrix( )
+ gl.glTranslate( 10, 100, 0 )
+ gl.glPushMatrix( )
+ gl.glListBase( base+1 )
+ gl.glCallLists( [ord(c) for c in text] )
+ gl.glPopMatrix( )
+ gl.glPopMatrix( )
+ glut.glutSwapBuffers( )
+
+def on_reshape( width, height ):
+ gl.glViewport( 0, 0, width, height )
+ gl.glMatrixMode( gl.GL_PROJECTION )
+ gl.glLoadIdentity( )
+ gl.glOrtho( 0, width, 0, height, -1, 1 )
+ gl.glMatrixMode( gl.GL_MODELVIEW )
+ gl.glLoadIdentity( )
+
+def on_keyboard( key, x, y ):
+ if key == '\033': sys.exit( )
+
+def makefont(filename, size):
+ global texid
+
+ # Load font and check it is monotype
+ face = Face(filename)
+ face.set_char_size( size*64 )
+ if not face.is_fixed_width:
+ raise 'Font is not monotype'
+
+ # Determine largest glyph size
+ width, height, ascender, descender = 0, 0, 0, 0
+ for c in range(32,128):
+ face.load_char( chr(c), FT_LOAD_RENDER | FT_LOAD_FORCE_AUTOHINT )
+ bitmap = face.glyph.bitmap
+ width = max( width, bitmap.width )
+ ascender = max( ascender, face.glyph.bitmap_top )
+ descender = max( descender, bitmap.rows-face.glyph.bitmap_top )
+ height = ascender+descender
+
+ # Generate texture data
+ Z = numpy.zeros((height*6, width*16), dtype=numpy.ubyte)
+ for j in range(6):
+ for i in range(16):
+ face.load_char(chr(32+j*16+i), FT_LOAD_RENDER | FT_LOAD_FORCE_AUTOHINT )
+ bitmap = face.glyph.bitmap
+ x = i*width + face.glyph.bitmap_left
+ y = j*height + ascender - face.glyph.bitmap_top
+ Z[y:y+bitmap.rows,x:x+bitmap.width].flat = bitmap.buffer
+
+ # Bound texture
+ texid = gl.glGenTextures(1)
+ gl.glBindTexture( gl.GL_TEXTURE_2D, texid )
+ gl.glTexParameterf( gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_LINEAR )
+ gl.glTexParameterf( gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, gl.GL_LINEAR )
+ gl.glTexImage2D( gl.GL_TEXTURE_2D, 0, gl.GL_ALPHA, Z.shape[1], Z.shape[0], 0,
+ gl.GL_ALPHA, gl.GL_UNSIGNED_BYTE, Z )
+
+ # Generate display lists
+ dx, dy = width/float(Z.shape[1]), height/float(Z.shape[0])
+ base = gl.glGenLists(8*16)
+ for i in range(8*16):
+ c = chr(i)
+ x = i%16
+ y = i//16-2
+ gl.glNewList(base+i, gl.GL_COMPILE)
+ if (c == '\n'):
+ gl.glPopMatrix( )
+ gl.glTranslatef( 0, -height, 0 )
+ gl.glPushMatrix( )
+ elif (c == '\t'):
+ gl.glTranslatef( 4*width, 0, 0 )
+ elif (i >= 32):
+ gl.glBegin( gl.GL_QUADS )
+ gl.glTexCoord2f( (x )*dx, (y+1)*dy ), gl.glVertex( 0, -height )
+ gl.glTexCoord2f( (x )*dx, (y )*dy ), gl.glVertex( 0, 0 )
+ gl.glTexCoord2f( (x+1)*dx, (y )*dy ), gl.glVertex( width, 0 )
+ gl.glTexCoord2f( (x+1)*dx, (y+1)*dy ), gl.glVertex( width, -height )
+ gl.glEnd( )
+ gl.glTranslatef( width, 0, 0 )
+ gl.glEndList( )
+
+
+if __name__ == '__main__':
+ import sys
+ glut.glutInit( sys.argv )
+ glut.glutInitDisplayMode( glut.GLUT_DOUBLE | glut.GLUT_RGB | glut.GLUT_DEPTH )
+ glut.glutCreateWindow( "Freetype OpenGL" )
+ glut.glutReshapeWindow( 600, 100 )
+ glut.glutDisplayFunc( on_display )
+ glut.glutReshapeFunc( on_reshape )
+ glut.glutKeyboardFunc( on_keyboard )
+ gl.glTexEnvf( gl.GL_TEXTURE_ENV, gl.GL_TEXTURE_ENV_MODE, gl.GL_MODULATE )
+ gl.glEnable( gl.GL_DEPTH_TEST )
+ gl.glEnable( gl.GL_BLEND )
+ gl.glEnable( gl.GL_COLOR_MATERIAL )
+ gl.glColorMaterial( gl.GL_FRONT_AND_BACK, gl.GL_AMBIENT_AND_DIFFUSE )
+ gl.glBlendFunc( gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA )
+ gl.glEnable( gl.GL_TEXTURE_2D )
+ makefont( './VeraMono.ttf', 64 )
+ glut.glutMainLoop( )
diff --git a/third_party/freetype-py/examples/sfnt-names.py b/third_party/freetype-py/examples/sfnt-names.py
new file mode 100644
index 0000000..ffebc00
--- /dev/null
+++ b/third_party/freetype-py/examples/sfnt-names.py
@@ -0,0 +1,66 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# -----------------------------------------------------------------------------
+# FreeType high-level python API - Copyright 2011 Nicolas P. Rougier
+# Distributed under the terms of the new BSD license.
+# -----------------------------------------------------------------------------
+from __future__ import print_function
+from __future__ import division
+from freetype import *
+
+def platform_name(platform_id):
+ for key, value in TT_PLATFORMS.items():
+ if value == platform_id:
+ return key
+ return 'Unknown platform'
+
+def encoding_name(platform_id, encoding_id):
+ if platform_id == TT_PLATFORM_APPLE_UNICODE:
+ encodings = TT_APPLE_IDS
+ elif platform_id == TT_PLATFORM_MACINTOSH:
+ encodings = TT_MAC_IDS
+ elif platform_id == TT_PLATFORM_MICROSOFT:
+ encodings = TT_MS_IDS
+ elif platform_id == TT_PLATFORM_ADOBE:
+ encodings = TT_ADOBE_IDS
+ else:
+ return 'Unknown encoding'
+ for key, value in encodings.items():
+ if value == encoding_id:
+ return key
+ return 'Unknown encoding'
+
+def language_name(platform_id, language_id):
+ if platform_id == TT_PLATFORM_MACINTOSH:
+ languages = TT_MAC_LANGIDS
+ elif platform_id == TT_PLATFORM_MICROSOFT:
+ languages = TT_MS_LANGIDS
+ else:
+ return 'Unknown language'
+ for key, value in languages.items():
+ if value == language_id:
+ return key
+ return 'Unknown language'
+
+
+if __name__ == '__main__':
+ import os, sys
+
+ if len(sys.argv) < 2:
+ print("Usage: %s font_filename" % sys.argv[0])
+ sys.exit()
+ face = Face(sys.argv[1])
+
+ name = face.get_sfnt_name(0)
+ print( 'platform_id:', platform_name(name.platform_id) )
+ print( 'encoding_id:', encoding_name(name.platform_id,
+ name.encoding_id) )
+ print( 'language_id:', language_name(name.platform_id,
+ name.language_id) )
+ for i in range(face.sfnt_name_count):
+ name = face.get_sfnt_name(i).string
+ print(i, name.decode('utf-8', 'ignore'))
+
+
+
+
diff --git a/third_party/freetype-py/examples/shader.py b/third_party/freetype-py/examples/shader.py
new file mode 100644
index 0000000..998dd8b
--- /dev/null
+++ b/third_party/freetype-py/examples/shader.py
@@ -0,0 +1,163 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# -----------------------------------------------------------------------------
+# Copyright (C) 2009-2010 Nicolas P. Rougier
+#
+# Distributed under the terms of the BSD License. The full license is in
+# the file COPYING, distributed as part of this software.
+# -----------------------------------------------------------------------------
+#
+# Copyright Tristam Macdonald 2008.
+#
+# Distributed under the Boost Software License, Version 1.0
+# (see http://www.boost.org/LICENSE_1_0.txt)
+#
+''' Base shader class.
+
+ Example:
+ --------
+ shader = Shader()
+
+ shader.bind()
+ glActiveTexture(GL_TEXTURE1)
+ glBindTexture(lut.target, lut.id)
+ shader.uniformi('lut', 1)
+
+ glActiveTexture(GL_TEXTURE0)
+ glBindTexture(texture.target, texture.id)
+ shader.uniformi('texture', 0)
+ shader.uniformf('pixel', 1.0/texture.width, 1.0/texture.height)
+
+ texture.blit(x,y,w,h)
+ shader.unbind()
+'''
+import os
+import OpenGL.GL as gl
+import ctypes
+
+class Shader:
+ ''' Base shader class. '''
+
+ def __init__(self, vert = None, frag = None, name=''):
+ ''' vert, frag and geom take arrays of source strings
+ the arrays will be concatenated into one string by OpenGL.'''
+
+ self.uniforms = {}
+ self.name = name
+ # create the program handle
+ self.handle = gl.glCreateProgram()
+ # we are not linked yet
+ self.linked = False
+ # create the vertex shader
+ self._build_shader(vert, gl.GL_VERTEX_SHADER)
+ # create the fragment shader
+ self._build_shader(frag, gl.GL_FRAGMENT_SHADER)
+ # the geometry shader will be the same, once pyglet supports the
+ # extension self.createShader(frag, GL_GEOMETRY_SHADER_EXT) attempt to
+ # link the program
+ self._link()
+
+ def _build_shader(self, strings, stype):
+ ''' Actual building of the shader '''
+
+ count = len(strings)
+ # if we have no source code, ignore this shader
+ if count < 1:
+ return
+
+ # create the shader handle
+ shader = gl.glCreateShader(stype)
+
+ # Upload shader code
+ gl.glShaderSource(shader, strings)
+
+ # compile the shader
+ gl.glCompileShader(shader)
+
+ # retrieve the compile status
+ status = gl.glGetShaderiv(shader, gl.GL_COMPILE_STATUS)
+
+ # if compilation failed, print the log
+ if not status:
+ # display the log
+ print gl.glGetShaderInfoLog(shader)
+ else:
+ # all is well, so attach the shader to the program
+ gl.glAttachShader(self.handle, shader)
+
+ def _link(self):
+ ''' Link the program '''
+
+ gl.glLinkProgram(self.handle)
+ # retrieve the link status
+ temp = ctypes.c_int(0)
+ gl.glGetProgramiv(self.handle, gl.GL_LINK_STATUS, ctypes.byref(temp))
+
+ # if linking failed, print the log
+ if not temp:
+ # retrieve the log length
+ gl.glGetProgramiv(self.handle,
+ gl.GL_INFO_LOG_LENGTH, ctypes.byref(temp))
+ # create a buffer for the log
+ #buffer = ctypes.create_string_buffer(temp.value)
+ # retrieve the log text
+ log = gl.glGetProgramInfoLog(self.handle) #, temp, None, buffer)
+ # print the log to the console
+ print log
+ else:
+ # all is well, so we are linked
+ self.linked = True
+
+ def bind(self):
+ ''' Bind the program, i.e. use it. '''
+ gl.glUseProgram(self.handle)
+
+ def unbind(self):
+ ''' Unbind whatever program is currently bound - not necessarily this
+ program, so this should probably be a class method instead. '''
+ gl.glUseProgram(0)
+
+ def uniformf(self, name, *vals):
+ ''' Uploads float uniform(s), program must be currently bound. '''
+
+ loc = self.uniforms.get(name,
+ gl.glGetUniformLocation(self.handle,name))
+ self.uniforms[name] = loc
+
+ # Check there are 1-4 values
+ if len(vals) in range(1, 5):
+ # Select the correct function
+ { 1 : gl.glUniform1f,
+ 2 : gl.glUniform2f,
+ 3 : gl.glUniform3f,
+ 4 : gl.glUniform4f
+ # Retrieve uniform location, and set it
+ }[len(vals)](loc, *vals)
+
+ def uniformi(self, name, *vals):
+ ''' Upload integer uniform(s), program must be currently bound. '''
+
+ loc = self.uniforms.get(name,
+ gl.glGetUniformLocation(self.handle,name))
+ self.uniforms[name] = loc
+
+ # Checks there are 1-4 values
+ if len(vals) in range(1, 5):
+ # Selects the correct function
+ { 1 : gl.glUniform1i,
+ 2 : gl.glUniform2i,
+ 3 : gl.glUniform3i,
+ 4 : gl.glUniform4i
+ # Retrieves uniform location, and set it
+ }[len(vals)](loc, *vals)
+
+
+ def uniform_matrixf(self, name, mat):
+ ''' Upload uniform matrix, program must be currently bound. '''
+
+ loc = self.uniforms.get(name,
+ gl.glGetUniformLocation(self.handle,name))
+ self.uniforms[name] = loc
+
+ # Upload the 4x4 floating point matrix
+ gl.glUniformMatrix4fv(loc, 1, False, (ctypes.c_float * 16)(*mat))
diff --git a/third_party/freetype-py/examples/subpixel-positioning.py b/third_party/freetype-py/examples/subpixel-positioning.py
new file mode 100644
index 0000000..6483517
--- /dev/null
+++ b/third_party/freetype-py/examples/subpixel-positioning.py
@@ -0,0 +1,236 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# -----------------------------------------------------------------------------
+#
+# FreeType high-level python API - Copyright 2011 Nicolas P. Rougier
+# Distributed under the terms of the new BSD license.
+#
+# -----------------------------------------------------------------------------
+'''
+Subpixel rendering AND positioning using OpenGL and shaders.
+
+'''
+import numpy as np
+import OpenGL.GL as gl
+import OpenGL.GLUT as glut
+from texture_font import TextureFont, TextureAtlas
+from shader import Shader
+
+
+vert='''
+uniform sampler2D texture;
+uniform vec2 pixel;
+attribute float modulo;
+varying float m;
+void main() {
+ gl_FrontColor = gl_Color;
+ gl_TexCoord[0].xy = gl_MultiTexCoord0.xy;
+ gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
+ m = modulo;
+}
+'''
+
+frag='''
+uniform sampler2D texture;
+uniform vec2 pixel;
+varying float m;
+void main() {
+ float gamma = 1.0;
+
+ vec2 uv = gl_TexCoord[0].xy;
+ vec4 current = texture2D(texture, uv);
+ vec4 previous= texture2D(texture, uv+vec2(-1,0)*pixel);
+
+ current = pow(current, vec4(1.0/gamma));
+ previous = pow(previous, vec4(1.0/gamma));
+
+ float r = current.r;
+ float g = current.g;
+ float b = current.b;
+ float a = current.a;
+ if( m <= 0.333 )
+ {
+ float z = m/0.333;
+ r = mix(current.r, previous.b, z);
+ g = mix(current.g, current.r, z);
+ b = mix(current.b, current.g, z);
+ }
+ else if( m <= 0.666 )
+ {
+ float z = (m-0.33)/0.333;
+ r = mix(previous.b, previous.g, z);
+ g = mix(current.r, previous.b, z);
+ b = mix(current.g, current.r, z);
+ }
+ else if( m < 1.0 )
+ {
+ float z = (m-0.66)/0.334;
+ r = mix(previous.g, previous.r, z);
+ g = mix(previous.b, previous.g, z);
+ b = mix(current.r, previous.b, z);
+ }
+
+ float t = max(max(r,g),b);
+ vec4 color = vec4(0.,0.,0., (r+g+b)/2.);
+ color = t*color + (1.-t)*vec4(r,g,b, min(min(r,g),b));
+ gl_FragColor = vec4( color.rgb, color.a);
+}
+'''
+
+
+
+
+
+class Label:
+ def __init__(self, text, font, color=(1.0, 1.0, 1.0, 0.0), x=0, y=0,
+ width=None, height=None, anchor_x='left', anchor_y='baseline'):
+ self.text = text
+ self.vertices = np.zeros((len(text)*4,3), dtype=np.float32)
+ self.indices = np.zeros((len(text)*6, ), dtype=np.uint)
+ self.colors = np.zeros((len(text)*4,4), dtype=np.float32)
+ self.texcoords= np.zeros((len(text)*4,2), dtype=np.float32)
+ self.attrib = np.zeros((len(text)*4,1), dtype=np.float32)
+ pen = [x,y]
+ prev = None
+
+ for i,charcode in enumerate(text):
+ glyph = font[charcode]
+ kerning = glyph.get_kerning(prev)
+ x0 = pen[0] + glyph.offset[0] + kerning
+ dx = x0-int(x0)
+ x0 = int(x0)
+ y0 = pen[1] + glyph.offset[1]
+ x1 = x0 + glyph.size[0]
+ y1 = y0 - glyph.size[1]
+ u0 = glyph.texcoords[0]
+ v0 = glyph.texcoords[1]
+ u1 = glyph.texcoords[2]
+ v1 = glyph.texcoords[3]
+
+ index = i*4
+ indices = [index, index+1, index+2, index, index+2, index+3]
+ vertices = [[x0,y0,1],[x0,y1,1],[x1,y1,1], [x1,y0,1]]
+ texcoords = [[u0,v0],[u0,v1],[u1,v1], [u1,v0]]
+ colors = [color,]*4
+
+ self.vertices[i*4:i*4+4] = vertices
+ self.indices[i*6:i*6+6] = indices
+ self.texcoords[i*4:i*4+4] = texcoords
+ self.colors[i*4:i*4+4] = colors
+ self.attrib[i*4:i*4+4] = dx
+ pen[0] = pen[0]+glyph.advance[0]/64.0 + kerning
+ pen[1] = pen[1]+glyph.advance[1]/64.0
+ prev = charcode
+
+ width = pen[0]-glyph.advance[0]/64.0+glyph.size[0]
+
+ if anchor_y == 'top':
+ dy = -round(font.ascender)
+ elif anchor_y == 'center':
+ dy = +round(-font.height/2-font.descender)
+ elif anchor_y == 'bottom':
+ dy = -round(font.descender)
+ else:
+ dy = 0
+
+ if anchor_x == 'right':
+ dx = -width/1.0
+ elif anchor_x == 'center':
+ dx = -width/2.0
+ else:
+ dx = 0
+ self.vertices += (round(dx), round(dy), 0)
+
+
+ def draw(self):
+ gl.glEnable( gl.GL_TEXTURE_2D )
+ gl.glDisable( gl.GL_DEPTH_TEST )
+
+ gl.glEnableClientState(gl.GL_VERTEX_ARRAY)
+ gl.glEnableClientState(gl.GL_COLOR_ARRAY)
+ gl.glEnableClientState(gl.GL_TEXTURE_COORD_ARRAY)
+ gl.glEnableClientState(gl.GL_VERTEX_ARRAY)
+
+ gl.glVertexPointer(3, gl.GL_FLOAT, 0, self.vertices)
+ gl.glColorPointer(4, gl.GL_FLOAT, 0, self.colors)
+ gl.glTexCoordPointer(2, gl.GL_FLOAT, 0, self.texcoords)
+
+ r,g,b = 0,0,0
+ gl.glColor( 1, 1, 1, 1 )
+ gl.glEnable( gl.GL_BLEND )
+ #gl.glBlendFunc( gl.GL_CONSTANT_COLOR_EXT, gl.GL_ONE_MINUS_SRC_COLOR )
+ #gl.glBlendColor(r,g,b,1)
+ gl.glBlendFunc( gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA )
+ gl.glBlendColor( 1, 1, 1, 1 )
+
+ gl.glEnableVertexAttribArray( 1 );
+ gl.glVertexAttribPointer( 1, 1, gl.GL_FLOAT, gl.GL_FALSE, 0, self.attrib)
+ shader.bind()
+ shader.uniformi('texture', 0)
+ shader.uniformf('pixel', 1.0/512, 1.0/512)
+ gl.glDrawElements(gl.GL_TRIANGLES, len(self.indices),
+ gl.GL_UNSIGNED_INT, self.indices)
+ shader.unbind()
+ gl.glDisableVertexAttribArray( 1 );
+ gl.glDisableClientState(gl.GL_VERTEX_ARRAY)
+ gl.glDisableClientState(gl.GL_COLOR_ARRAY)
+ gl.glDisableClientState(gl.GL_TEXTURE_COORD_ARRAY)
+ gl.glDisable( gl.GL_TEXTURE_2D )
+ gl.glDisable( gl.GL_BLEND )
+
+
+
+
+if __name__ == '__main__':
+ import sys
+
+ atlas = TextureAtlas(512,512,3)
+
+ def on_display( ):
+ #gl.glClearColor(0,0,0,1)
+ gl.glClearColor(1,1,1,1)
+ gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT)
+ gl.glBindTexture( gl.GL_TEXTURE_2D, atlas.texid )
+ for label in labels:
+ label.draw()
+
+ gl.glColor(0,0,0,1)
+ gl.glBegin(gl.GL_LINES)
+ gl.glVertex2i(15,0)
+ gl.glVertex2i(15, 330)
+ gl.glVertex2i(225, 0)
+ gl.glVertex2i(225, 330)
+ gl.glEnd()
+ glut.glutSwapBuffers( )
+
+ def on_reshape( width, height ):
+ gl.glViewport( 0, 0, width, height )
+ gl.glMatrixMode( gl.GL_PROJECTION )
+ gl.glLoadIdentity( )
+ gl.glOrtho( 0, width, 0, height, -1, 1 )
+ gl.glMatrixMode( gl.GL_MODELVIEW )
+ gl.glLoadIdentity( )
+
+ def on_keyboard( key, x, y ):
+ if key == '\033':
+ sys.exit( )
+
+ glut.glutInit( sys.argv )
+ glut.glutInitDisplayMode( glut.GLUT_DOUBLE | glut.GLUT_RGBA | glut.GLUT_DEPTH )
+ glut.glutCreateWindow( "Freetype OpenGL" )
+ glut.glutReshapeWindow( 240, 330 )
+ glut.glutDisplayFunc( on_display )
+ glut.glutReshapeFunc( on_reshape )
+ glut.glutKeyboardFunc( on_keyboard )
+
+ font = TextureFont(atlas, './Arial.ttf', 9)
+ text = "|... A Quick Brown Fox Jumps Over The Lazy Dog"
+ labels = []
+ x,y = 20,310
+ for i in range(30):
+ labels.append(Label(text=text, font=font, x=x, y=y))
+ x += 0.1000000000001
+ y -= 10
+ atlas.upload()
+ shader = Shader(vert,frag)
+ glut.glutMainLoop( )
diff --git a/third_party/freetype-py/examples/texture_font.py b/third_party/freetype-py/examples/texture_font.py
new file mode 100644
index 0000000..8abdd2e
--- /dev/null
+++ b/third_party/freetype-py/examples/texture_font.py
@@ -0,0 +1,421 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# -----------------------------------------------------------------------------
+#
+# FreeType high-level python API - Copyright 2011 Nicolas P. Rougier
+# Distributed under the terms of the new BSD license.
+#
+# -----------------------------------------------------------------------------
+'''
+Texture font class
+
+'''
+import sys
+import math
+import numpy as np
+import OpenGL.GL as gl
+from freetype import *
+
+
+class TextureAtlas:
+ '''
+ Group multiple small data regions into a larger texture.
+
+ The algorithm is based on the article by Jukka Jylänki : "A Thousand Ways
+ to Pack the Bin - A Practical Approach to Two-Dimensional Rectangle Bin
+ Packing", February 27, 2010. More precisely, this is an implementation of
+ the Skyline Bottom-Left algorithm based on C++ sources provided by Jukka
+ Jylänki at: http://clb.demon.fi/files/RectangleBinPack/
+
+ Example usage:
+ --------------
+
+ atlas = TextureAtlas(512,512,3)
+ region = atlas.get_region(20,20)
+ ...
+ atlas.set_region(region, data)
+ '''
+
+ def __init__(self, width=1024, height=1024, depth=1):
+ '''
+ Initialize a new atlas of given size.
+
+ Parameters
+ ----------
+
+ width : int
+ Width of the underlying texture
+
+ height : int
+ Height of the underlying texture
+
+ depth : 1 or 3
+ Depth of the underlying texture
+ '''
+ self.width = int(math.pow(2, int(math.log(width, 2) + 0.5)))
+ self.height = int(math.pow(2, int(math.log(height, 2) + 0.5)))
+ self.depth = depth
+ self.nodes = [ (0,0,self.width), ]
+ self.data = np.zeros((self.height, self.width, self.depth),
+ dtype=np.ubyte)
+ self.texid = 0
+ self.used = 0
+
+
+
+ def upload(self):
+ '''
+ Upload atlas data into video memory.
+ '''
+
+ if not self.texid:
+ self.texid = gl.glGenTextures(1)
+
+ gl.glBindTexture( gl.GL_TEXTURE_2D, self.texid )
+ gl.glTexParameteri( gl.GL_TEXTURE_2D,
+ gl.GL_TEXTURE_WRAP_S, gl.GL_CLAMP )
+ gl.glTexParameteri( gl.GL_TEXTURE_2D,
+ gl.GL_TEXTURE_WRAP_T, gl.GL_CLAMP )
+ gl.glTexParameteri( gl.GL_TEXTURE_2D,
+ gl.GL_TEXTURE_MAG_FILTER, gl.GL_LINEAR )
+ gl.glTexParameteri( gl.GL_TEXTURE_2D,
+ gl.GL_TEXTURE_MIN_FILTER, gl.GL_LINEAR )
+ if self.depth == 1:
+ gl.glTexImage2D( gl.GL_TEXTURE_2D, 0, gl.GL_ALPHA,
+ self.width, self.height, 0,
+ gl.GL_ALPHA, gl.GL_UNSIGNED_BYTE, self.data )
+ else:
+ gl.glTexImage2D( gl.GL_TEXTURE_2D, 0, gl.GL_RGB,
+ self.width, self.height, 0,
+ gl.GL_RGB, gl.GL_UNSIGNED_BYTE, self.data )
+
+
+
+ def set_region(self, region, data):
+ '''
+ Set a given region width provided data.
+
+ Parameters
+ ----------
+
+ region : (int,int,int,int)
+ an allocated region (x,y,width,height)
+
+ data : numpy array
+ data to be copied into given region
+ '''
+
+ x, y, width, height = region
+ self.data[y:y+height,x:x+width, :] = data
+
+
+
+ def get_region(self, width, height):
+ '''
+ Get a free region of given size and allocate it
+
+ Parameters
+ ----------
+
+ width : int
+ Width of region to allocate
+
+ height : int
+ Height of region to allocate
+
+ Return
+ ------
+ A newly allocated region as (x,y,width,height) or (-1,-1,0,0)
+ '''
+
+ best_height = sys.maxint
+ best_index = -1
+ best_width = sys.maxint
+ region = 0, 0, width, height
+
+ for i in range(len(self.nodes)):
+ y = self.fit(i, width, height)
+ if y >= 0:
+ node = self.nodes[i]
+ if (y+height < best_height or
+ (y+height == best_height and node[2] < best_width)):
+ best_height = y+height
+ best_index = i
+ best_width = node[2]
+ region = node[0], y, width, height
+
+ if best_index == -1:
+ return -1,-1,0,0
+
+ node = region[0], region[1]+height, width
+ self.nodes.insert(best_index, node)
+
+ i = best_index+1
+ while i < len(self.nodes):
+ node = self.nodes[i]
+ prev_node = self.nodes[i-1]
+ if node[0] < prev_node[0]+prev_node[2]:
+ shrink = prev_node[0]+prev_node[2] - node[0]
+ x,y,w = self.nodes[i]
+ self.nodes[i] = x+shrink, y, w-shrink
+ if self.nodes[i][2] <= 0:
+ del self.nodes[i]
+ i -= 1
+ else:
+ break
+ else:
+ break
+ i += 1
+
+ self.merge()
+ self.used += width*height
+ return region
+
+
+
+ def fit(self, index, width, height):
+ '''
+ Test if region (width,height) fit into self.nodes[index]
+
+ Parameters
+ ----------
+
+ index : int
+ Index of the internal node to be tested
+
+ width : int
+ Width or the region to be tested
+
+ height : int
+ Height or the region to be tested
+
+ '''
+
+ node = self.nodes[index]
+ x,y = node[0], node[1]
+ width_left = width
+
+ if x+width > self.width:
+ return -1
+
+ i = index
+ while width_left > 0:
+ node = self.nodes[i]
+ y = max(y, node[1])
+ if y+height > self.height:
+ return -1
+ width_left -= node[2]
+ i += 1
+ return y
+
+
+
+ def merge(self):
+ '''
+ Merge nodes
+ '''
+
+ i = 0
+ while i < len(self.nodes)-1:
+ node = self.nodes[i]
+ next_node = self.nodes[i+1]
+ if node[1] == next_node[1]:
+ self.nodes[i] = node[0], node[1], node[2]+next_node[2]
+ del self.nodes[i+1]
+ else:
+ i += 1
+
+
+class TextureFont:
+ '''
+ A texture font gathers a set of glyph relatively to a given font filename
+ and size.
+ '''
+
+ def __init__(self, atlas, filename, size):
+ '''
+ Initialize font
+
+ Parameters:
+ -----------
+
+ atlas: TextureAtlas
+ Texture atlas where glyph texture will be stored
+
+ filename: str
+ Font filename
+
+ size : float
+ Font size
+ '''
+ self.atlas = atlas
+ self.filename = filename
+ self.size = size
+ self.glyphs = {}
+ face = Face( self.filename )
+ face.set_char_size( int(self.size*64))
+ self._dirty = False
+ metrics = face.size
+ self.ascender = metrics.ascender/64.0
+ self.descender = metrics.descender/64.0
+ self.height = metrics.height/64.0
+ self.linegap = self.height - self.ascender + self.descender
+ self.depth = atlas.depth
+ set_lcd_filter(FT_LCD_FILTER_LIGHT)
+
+
+ def __getitem__(self, charcode):
+ '''
+ x.__getitem__(y) <==> x[y]
+ '''
+ if charcode not in self.glyphs.keys():
+ self.load('%c' % charcode)
+ return self.glyphs[charcode]
+
+
+
+ def get_texid(self):
+ '''
+ Get underlying texture identity .
+ '''
+
+ if self._dirty:
+ self.atlas.upload()
+ self._dirty = False
+ return self.atlas.texid
+
+ texid = property(get_texid,
+ doc='''Underlying texture identity.''')
+
+
+
+ def load(self, charcodes = ''):
+ '''
+ Build glyphs corresponding to individual characters in charcodes.
+
+ Parameters:
+ -----------
+
+ charcodes: [str | unicode]
+ Set of characters to be represented
+ '''
+ face = Face( self.filename )
+ pen = Vector(0,0)
+ hres = 16*72
+ hscale = 1.0/16
+
+ for charcode in charcodes:
+ face.set_char_size( int(self.size * 64), 0, hres, 72 )
+ matrix = Matrix( int((hscale) * 0x10000L), int((0.0) * 0x10000L),
+ int((0.0) * 0x10000L), int((1.0) * 0x10000L) )
+ face.set_transform( matrix, pen )
+ if charcode in self.glyphs.keys():
+ continue
+
+ self.dirty = True
+ flags = FT_LOAD_RENDER | FT_LOAD_FORCE_AUTOHINT
+ flags |= FT_LOAD_TARGET_LCD
+
+ face.load_char( charcode, flags )
+ bitmap = face.glyph.bitmap
+ left = face.glyph.bitmap_left
+ top = face.glyph.bitmap_top
+ width = face.glyph.bitmap.width
+ rows = face.glyph.bitmap.rows
+ pitch = face.glyph.bitmap.pitch
+
+ x,y,w,h = self.atlas.get_region(width/self.depth+2, rows+2)
+ if x < 0:
+ print 'Missed !'
+ continue
+ x,y = x+1, y+1
+ w,h = w-2, h-2
+ data = []
+ for i in range(rows):
+ data.extend(bitmap.buffer[i*pitch:i*pitch+width])
+ data = np.array(data,dtype=np.ubyte).reshape(h,w,3)
+ gamma = 1.5
+ Z = ((data/255.0)**(gamma))
+ data = (Z*255).astype(np.ubyte)
+ self.atlas.set_region((x,y,w,h), data)
+
+ # Build glyph
+ size = w,h
+ offset = left, top
+ advance= face.glyph.advance.x, face.glyph.advance.y
+
+ u0 = (x + 0.0)/float(self.atlas.width)
+ v0 = (y + 0.0)/float(self.atlas.height)
+ u1 = (x + w - 0.0)/float(self.atlas.width)
+ v1 = (y + h - 0.0)/float(self.atlas.height)
+ texcoords = (u0,v0,u1,v1)
+ glyph = TextureGlyph(charcode, size, offset, advance, texcoords)
+ self.glyphs[charcode] = glyph
+
+ # Generate kerning
+ for g in self.glyphs.values():
+ # 64 * 64 because of 26.6 encoding AND the transform matrix used
+ # in texture_font_load_face (hres = 64)
+ kerning = face.get_kerning(g.charcode, charcode, mode=FT_KERNING_UNFITTED)
+ if kerning.x != 0:
+ glyph.kerning[g.charcode] = kerning.x/(64.0*64.0)
+ kerning = face.get_kerning(charcode, g.charcode, mode=FT_KERNING_UNFITTED)
+ if kerning.x != 0:
+ g.kerning[charcode] = kerning.x/(64.0*64.0)
+
+ # High resolution advance.x calculation
+ # gindex = face.get_char_index( charcode )
+ # a = face.get_advance(gindex, FT_LOAD_RENDER | FT_LOAD_TARGET_LCD)/(64*72)
+ # glyph.advance = a, glyph.advance[1]
+
+
+class TextureGlyph:
+ '''
+ A texture glyph gathers information relative to the size/offset/advance and
+ texture coordinates of a single character. It is generally built
+ automatically by a TextureFont.
+ '''
+
+ def __init__(self, charcode, size, offset, advance, texcoords):
+ '''
+ Build a new texture glyph
+
+ Parameter:
+ ----------
+
+ charcode : char
+ Represented character
+
+ size: tuple of 2 ints
+ Glyph size in pixels
+
+ offset: tuple of 2 floats
+ Glyph offset relatively to anchor point
+
+ advance: tuple of 2 floats
+ Glyph advance
+
+ texcoords: tuple of 4 floats
+ Texture coordinates of bottom-left and top-right corner
+ '''
+ self.charcode = charcode
+ self.size = size
+ self.offset = offset
+ self.advance = advance
+ self.texcoords = texcoords
+ self.kerning = {}
+
+
+ def get_kerning(self, charcode):
+ ''' Get kerning information
+
+ Parameters:
+ -----------
+
+ charcode: char
+ Character preceding this glyph
+ '''
+ if charcode in self.kerning.keys():
+ return self.kerning[charcode]
+ else:
+ return 0
diff --git a/third_party/freetype-py/examples/wordle.py b/third_party/freetype-py/examples/wordle.py
new file mode 100644
index 0000000..249f86d
--- /dev/null
+++ b/third_party/freetype-py/examples/wordle.py
@@ -0,0 +1,137 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# -----------------------------------------------------------------------------
+#
+# FreeType high-level python API - Copyright 2011 Nicolas P. Rougier
+# Distributed under the terms of the new BSD license.
+#
+# -----------------------------------------------------------------------------
+import math
+import numpy as np
+from freetype import *
+import matplotlib.pyplot as plt
+
+
+def make_label(text, filename, size=12, angle=0):
+ '''
+ Parameters:
+ -----------
+ text : string
+ Text to be displayed
+ filename : string
+ Path to a font
+ size : int
+ Font size in 1/64th points
+ angle : float
+ Text angle in degrees
+ '''
+ face = Face(filename)
+ face.set_char_size( size*64 )
+ angle = (angle/180.0)*math.pi
+ matrix = FT_Matrix( (int)( math.cos( angle ) * 0x10000L ),
+ (int)(-math.sin( angle ) * 0x10000L ),
+ (int)( math.sin( angle ) * 0x10000L ),
+ (int)( math.cos( angle ) * 0x10000L ))
+ flags = FT_LOAD_RENDER
+ pen = FT_Vector(0,0)
+ FT_Set_Transform( face._FT_Face, byref(matrix), byref(pen) )
+ previous = 0
+ xmin, xmax = 0, 0
+ ymin, ymax = 0, 0
+ for c in text:
+ face.load_char(c, flags)
+ kerning = face.get_kerning(previous, c)
+ previous = c
+ bitmap = face.glyph.bitmap
+ pitch = face.glyph.bitmap.pitch
+ width = face.glyph.bitmap.width
+ rows = face.glyph.bitmap.rows
+ top = face.glyph.bitmap_top
+ left = face.glyph.bitmap_left
+ pen.x += kerning.x
+ x0 = (pen.x >> 6) + left
+ x1 = x0 + width
+ y0 = (pen.y >> 6) - (rows - top)
+ y1 = y0 + rows
+ xmin, xmax = min(xmin, x0), max(xmax, x1)
+ ymin, ymax = min(ymin, y0), max(ymax, y1)
+ pen.x += face.glyph.advance.x
+ pen.y += face.glyph.advance.y
+
+ L = np.zeros((ymax-ymin, xmax-xmin),dtype=np.ubyte)
+ previous = 0
+ pen.x, pen.y = 0, 0
+ for c in text:
+ face.load_char(c, flags)
+ kerning = face.get_kerning(previous, c)
+ previous = c
+ bitmap = face.glyph.bitmap
+ pitch = face.glyph.bitmap.pitch
+ width = face.glyph.bitmap.width
+ rows = face.glyph.bitmap.rows
+ top = face.glyph.bitmap_top
+ left = face.glyph.bitmap_left
+ pen.x += kerning.x
+ x = (pen.x >> 6) - xmin + left
+ y = (pen.y >> 6) - ymin - (rows - top)
+ data = []
+ for j in range(rows):
+ data.extend(bitmap.buffer[j*pitch:j*pitch+width])
+ if len(data):
+ Z = np.array(data,dtype=np.ubyte).reshape(rows, width)
+ L[y:y+rows,x:x+width] |= Z[::-1,::1]
+ pen.x += face.glyph.advance.x
+ pen.y += face.glyph.advance.y
+
+ return L
+
+
+if __name__ == '__main__':
+ from PIL import Image
+
+ n_words = 100
+ H, W, dpi = 600, 800, 72.0
+ I = np.zeros((H, W, 3), dtype=np.ubyte)
+ S = np.random.normal(0,1,n_words)
+ S = (S-S.min())/(S.max()-S.min())
+ S = np.sort(1-np.sqrt(S))[::-1]
+ sizes = (12 + S*48).astype(int).tolist()
+
+ def spiral():
+ eccentricity = 1.5
+ radius = 8
+ step = 0.1
+ t = 0
+ while True:
+ t += step
+ yield eccentricity*radius*t*math.cos(t), radius*t*math.sin(t)
+
+ fails = 0
+ for size in sizes:
+ angle = np.random.randint(-25,25)
+ L = make_label('Hello', './Vera.ttf', size, angle=angle)
+ h,w = L.shape
+ if h < H and w < W:
+ x0 = W//2 + (np.random.uniform()-.1)*50
+ y0 = H//2 + (np.random.uniform()-.1)*50
+ for dx,dy in spiral():
+ c = .25+.75*np.random.random()
+ x = int(x0+dx)
+ y = int(y0+dy)
+ if x <= w//2 or y <= h//2 or x >= (W-w//2) or y >= (H-h//2):
+ fails += 1
+ break
+ if (I[y-h//2:y-h//2+h, x-w//2:x-w//2+w,0] * L).sum() == 0:
+ I[y-h//2:y-h//2+h, x-w//2:x-w//2+w,0] |= (c * L).astype(int)
+ I[y-h//2:y-h//2+h, x-w//2:x-w//2+w,1] |= (c * L).astype(int)
+ I[y-h//2:y-h//2+h, x-w//2:x-w//2+w,2] |= (c * L).astype(int)
+ break
+
+ print "Number of fails:", fails
+ fig = plt.figure(figsize=(W/dpi,H/dpi), dpi=dpi)
+ ax = fig.add_axes([0,0,1,1], frameon=False)
+ ax.imshow(I, interpolation='nearest', cmap=plt.cm.gray, origin='upper')
+ #plt.axis('off')
+ plt.show()
+ I = Image.fromarray(I[::-1,::1,::1], mode='RGB')
+ I.save('wordle.png')
diff --git a/third_party/freetype-py/freetype/__init__.py b/third_party/freetype-py/freetype/__init__.py
new file mode 100644
index 0000000..3f9934e
--- /dev/null
+++ b/third_party/freetype-py/freetype/__init__.py
@@ -0,0 +1,1989 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# -----------------------------------------------------------------------------
+#
+# FreeType high-level python API - Copyright 2011-2014 Nicolas P. Rougier
+# Distributed under the terms of the new BSD license.
+#
+# -----------------------------------------------------------------------------
+'''
+FreeType high-level python API
+
+This the bindings for the high-level API of FreeType (that must be installed
+somewhere on your system).
+
+Note: C Library will be searched using the ctypes.util.find_library. However,
+ this search might fail. In such a case (or for other reasons), you may
+ have to specify an explicit path below.
+'''
+import os
+import sys
+import platform
+from ctypes import *
+from freetype.ft_types import *
+from freetype.ft_enums import *
+from freetype.ft_errors import *
+from freetype.ft_structs import *
+import ctypes.util
+
+# Hack to get unicode class in python3
+PY3 = sys.version_info[0] == 3
+if PY3: unicode = str
+
+
+__dll__ = None
+__handle__ = None
+
+# on windows all ctypes does when checking for the library
+# is to append .dll to the end and look for an exact match
+# within any entry in PATH.
+filename = ctypes.util.find_library('freetype')
+
+if filename is None:
+ if platform.system() == 'Windows':
+ # Check current working directory for dll as ctypes fails to do so
+ filename = os.path.join(os.path.realpath('.'), 'freetype.dll')
+ else:
+ filename = 'libfreetype.so.6'
+
+try:
+ dll = ctypes.CDLL(filename)
+ _found = True
+except (OSError, TypeError):
+ _found = False
+
+if not _found:
+ raise RuntimeError('Freetype library not found')
+
+__dll__ = dll
+FT_Library_filename = filename
+
+# -----------------------------------------------------------------------------
+# High-level API of FreeType 2
+# -----------------------------------------------------------------------------
+FT_Init_FreeType = __dll__.FT_Init_FreeType
+FT_Done_FreeType = __dll__.FT_Done_FreeType
+FT_Library_Version = __dll__.FT_Library_Version
+
+def __del_library__(self):
+ global __handle__
+ if __handle__:
+ try:
+ FT_Done_FreeType(self)
+ __handle__ = None
+ except:
+ pass
+FT_Library.__del__ = __del_library__
+
+def get_handle():
+ '''
+ Get unique FT_Library handle
+ '''
+ global __handle__
+ if not __handle__:
+ __handle__ = FT_Library( )
+ error = FT_Init_FreeType( byref(__handle__) )
+ if error: raise FT_Exception(error)
+ try:
+ set_lcd_filter( FT_LCD_FILTER_DEFAULT )
+ except:
+ pass
+ if error: raise FT_Exception(error)
+ return __handle__
+
+def version():
+ '''
+ Return the version of the FreeType library being used as a tuple of
+ ( major version number, minor version number, patch version number )
+ '''
+ amajor = FT_Int()
+ aminor = FT_Int()
+ apatch = FT_Int()
+ library = get_handle()
+ FT_Library_Version(library, byref(amajor), byref(aminor), byref(apatch))
+ return (amajor.value, aminor.value, apatch.value)
+
+
+try:
+ FT_Library_SetLcdFilter= __dll__.FT_Library_SetLcdFilter
+except:
+ def FT_Library_SetLcdFilter (*args, **kwargs):
+ return 0
+if version()>=(2,4,0):
+ FT_Library_SetLcdFilterWeights = __dll__.FT_Library_SetLcdFilterWeights
+FT_New_Face = __dll__.FT_New_Face
+FT_New_Memory_Face = __dll__.FT_New_Memory_Face
+FT_Open_Face = __dll__.FT_Open_Face
+FT_Attach_File = __dll__.FT_Attach_File
+FT_Attach_Stream = __dll__.FT_Attach_Stream
+if version()>=(2,4,2):
+ FT_Reference_Face = __dll__.FT_Reference_Face
+FT_Done_Face = __dll__.FT_Done_Face
+FT_Done_Glyph = __dll__.FT_Done_Glyph
+FT_Select_Size = __dll__.FT_Select_Size
+FT_Request_Size = __dll__.FT_Request_Size
+FT_Set_Char_Size = __dll__.FT_Set_Char_Size
+FT_Set_Pixel_Sizes = __dll__.FT_Set_Pixel_Sizes
+FT_Load_Glyph = __dll__.FT_Load_Glyph
+FT_Load_Char = __dll__.FT_Load_Char
+FT_Set_Transform = __dll__.FT_Set_Transform
+FT_Render_Glyph = __dll__.FT_Render_Glyph
+FT_Get_Kerning = __dll__.FT_Get_Kerning
+FT_Get_Track_Kerning = __dll__.FT_Get_Track_Kerning
+FT_Get_Glyph_Name = __dll__.FT_Get_Glyph_Name
+FT_Get_Glyph = __dll__.FT_Get_Glyph
+
+FT_Glyph_Get_CBox = __dll__.FT_Glyph_Get_CBox
+
+FT_Get_Postscript_Name = __dll__.FT_Get_Postscript_Name
+FT_Get_Postscript_Name.restype = c_char_p
+FT_Select_Charmap = __dll__.FT_Select_Charmap
+FT_Set_Charmap = __dll__.FT_Set_Charmap
+FT_Get_Charmap_Index = __dll__.FT_Get_Charmap_Index
+FT_Get_CMap_Language_ID= __dll__.FT_Get_CMap_Language_ID
+FT_Get_CMap_Format = __dll__.FT_Get_CMap_Format
+FT_Get_Char_Index = __dll__.FT_Get_Char_Index
+FT_Get_First_Char = __dll__.FT_Get_First_Char
+FT_Get_Next_Char = __dll__.FT_Get_Next_Char
+FT_Get_Name_Index = __dll__.FT_Get_Name_Index
+FT_Get_SubGlyph_Info = __dll__.FT_Get_SubGlyph_Info
+if version()>=(2,3,8):
+ FT_Get_FSType_Flags = __dll__.FT_Get_FSType_Flags
+ FT_Get_FSType_Flags.restype = c_ushort
+
+FT_Get_X11_Font_Format = __dll__.FT_Get_X11_Font_Format
+FT_Get_X11_Font_Format.restype = c_char_p
+
+FT_Get_Sfnt_Name_Count = __dll__.FT_Get_Sfnt_Name_Count
+FT_Get_Sfnt_Name = __dll__.FT_Get_Sfnt_Name
+FT_Get_Advance = __dll__.FT_Get_Advance
+
+
+FT_Outline_GetInsideBorder = __dll__.FT_Outline_GetInsideBorder
+FT_Outline_GetOutsideBorder = __dll__.FT_Outline_GetOutsideBorder
+FT_Outline_Get_BBox = __dll__.FT_Outline_Get_BBox
+FT_Outline_Get_CBox = __dll__.FT_Outline_Get_CBox
+FT_Stroker_New = __dll__.FT_Stroker_New
+FT_Stroker_Set = __dll__.FT_Stroker_Set
+FT_Stroker_Rewind = __dll__.FT_Stroker_Rewind
+FT_Stroker_ParseOutline = __dll__.FT_Stroker_ParseOutline
+FT_Stroker_BeginSubPath = __dll__.FT_Stroker_BeginSubPath
+FT_Stroker_EndSubPath = __dll__.FT_Stroker_EndSubPath
+FT_Stroker_LineTo = __dll__.FT_Stroker_LineTo
+FT_Stroker_ConicTo = __dll__.FT_Stroker_ConicTo
+FT_Stroker_CubicTo = __dll__.FT_Stroker_CubicTo
+FT_Stroker_GetBorderCounts = __dll__.FT_Stroker_GetBorderCounts
+FT_Stroker_ExportBorder = __dll__.FT_Stroker_ExportBorder
+FT_Stroker_GetCounts = __dll__.FT_Stroker_GetCounts
+FT_Stroker_Export = __dll__.FT_Stroker_Export
+FT_Stroker_Done = __dll__.FT_Stroker_Done
+FT_Glyph_Stroke = __dll__.FT_Glyph_Stroke
+FT_Glyph_StrokeBorder = __dll__.FT_Glyph_StrokeBorder
+FT_Glyph_To_Bitmap = __dll__.FT_Glyph_To_Bitmap
+
+
+
+# -----------------------------------------------------------------------------
+# Stand alone functions
+# -----------------------------------------------------------------------------
+def set_lcd_filter(filt):
+ '''
+ This function is used to apply color filtering to LCD decimated bitmaps,
+ like the ones used when calling FT_Render_Glyph with FT_RENDER_MODE_LCD or
+ FT_RENDER_MODE_LCD_V.
+
+ **Note**
+
+ This feature is always disabled by default. Clients must make an explicit
+ call to this function with a 'filter' value other than FT_LCD_FILTER_NONE
+ in order to enable it.
+
+ Due to PATENTS covering subpixel rendering, this function doesn't do
+ anything except returning 'FT_Err_Unimplemented_Feature' if the
+ configuration macro FT_CONFIG_OPTION_SUBPIXEL_RENDERING is not defined in
+ your build of the library, which should correspond to all default builds of
+ FreeType.
+
+ The filter affects glyph bitmaps rendered through FT_Render_Glyph,
+ FT_Outline_Get_Bitmap, FT_Load_Glyph, and FT_Load_Char.
+
+ It does not affect the output of FT_Outline_Render and
+ FT_Outline_Get_Bitmap.
+
+ If this feature is activated, the dimensions of LCD glyph bitmaps are
+ either larger or taller than the dimensions of the corresponding outline
+ with regards to the pixel grid. For example, for FT_RENDER_MODE_LCD, the
+ filter adds up to 3 pixels to the left, and up to 3 pixels to the right.
+
+ The bitmap offset values are adjusted correctly, so clients shouldn't need
+ to modify their layout and glyph positioning code when enabling the filter.
+ '''
+ library = get_handle()
+ error = FT_Library_SetLcdFilter(library, filt)
+ if error: raise FT_Exception(error)
+
+
+
+def set_lcd_filter_weights(a,b,c,d,e):
+ '''
+ Use this function to override the filter weights selected by
+ FT_Library_SetLcdFilter. By default, FreeType uses the quintuple (0x00,
+ 0x55, 0x56, 0x55, 0x00) for FT_LCD_FILTER_LIGHT, and (0x10, 0x40, 0x70,
+ 0x40, 0x10) for FT_LCD_FILTER_DEFAULT and FT_LCD_FILTER_LEGACY.
+
+ **Note**
+
+ Only available if version > 2.4.0
+ '''
+ if version()>=(2,4,0):
+ library = get_handle()
+ weights = FT_Char(5)(a,b,c,d,e)
+ error = FT_Library_SetLcdFilterWeights(library, weights)
+ if error: raise FT_Exception(error)
+ else:
+ raise RuntimeError(
+ 'set_lcd_filter_weights require freetype > 2.4.0')
+
+
+def _encode_filename(filename):
+ encoded = filename.encode(sys.getfilesystemencoding())
+ if "?" not in filename and b"?" in encoded:
+ # A bug, decoding mbcs always ignore exception, still isn't fixed in Python 2,
+ # view http://bugs.python.org/issue850997 for detail
+ raise UnicodeError()
+ return encoded
+
+
+
+# -----------------------------------------------------------------------------
+# Direct wrapper (simple renaming)
+# -----------------------------------------------------------------------------
+Vector = FT_Vector
+Matrix = FT_Matrix
+
+
+
+# -----------------------------------------------------------------------------
+class BBox( object ):
+ '''
+ FT_BBox wrapper.
+
+ A structure used to hold an outline's bounding box, i.e., the coordinates
+ of its extrema in the horizontal and vertical directions.
+
+ **Note**
+
+ The bounding box is specified with the coordinates of the lower left and
+ the upper right corner. In PostScript, those values are often called
+ (llx,lly) and (urx,ury), respectively.
+
+ If 'yMin' is negative, this value gives the glyph's descender. Otherwise,
+ the glyph doesn't descend below the baseline. Similarly, if 'ymax' is
+ positive, this value gives the glyph's ascender.
+
+ 'xMin' gives the horizontal distance from the glyph's origin to the left
+ edge of the glyph's bounding box. If 'xMin' is negative, the glyph
+ extends to the left of the origin.
+ '''
+
+ def __init__(self, bbox):
+ '''
+ Create a new BBox object.
+
+ :param bbox: a FT_BBox or a tuple of 4 values
+ '''
+ if type(bbox) is FT_BBox:
+ self._FT_BBox = bbox
+ else:
+ self._FT_BBox = FT_BBox(*bbox)
+
+ xMin = property(lambda self: self._FT_BBox.xMin,
+ doc = 'The horizontal minimum (left-most).')
+
+ yMin = property(lambda self: self._FT_BBox.yMin,
+ doc = 'The vertical minimum (bottom-most).')
+
+ xMax = property(lambda self: self._FT_BBox.xMax,
+ doc = 'The horizontal maximum (right-most).')
+
+ yMax = property(lambda self: self._FT_BBox.yMax,
+ doc = 'The vertical maximum (top-most).')
+
+
+
+
+
+# -----------------------------------------------------------------------------
+class GlyphMetrics( object ):
+ '''
+
+ A structure used to model the metrics of a single glyph. The values are
+ expressed in 26.6 fractional pixel format; if the flag FT_LOAD_NO_SCALE has
+ been used while loading the glyph, values are expressed in font units
+ instead.
+
+ **Note**
+
+ If not disabled with FT_LOAD_NO_HINTING, the values represent dimensions of
+ the hinted glyph (in case hinting is applicable).
+
+ Stroking a glyph with an outside border does not increase ‘horiAdvance’ or
+ ‘vertAdvance’; you have to manually adjust these values to account for the
+ added width and height.
+ '''
+
+ def __init__(self, metrics ):
+ '''
+ Create a new GlyphMetrics object.
+
+ :param metrics: a FT_Glyph_Metrics
+ '''
+ self._FT_Glyph_Metrics = metrics
+
+ width = property( lambda self: self._FT_Glyph_Metrics.width,
+ doc = '''The glyph's width.''' )
+
+ height = property( lambda self: self._FT_Glyph_Metrics.height,
+ doc = '''The glyph's height.''' )
+
+ horiBearingX = property( lambda self: self._FT_Glyph_Metrics.horiBearingX,
+ doc = '''Left side bearing for horizontal layout.''' )
+
+ horiBearingY = property( lambda self: self._FT_Glyph_Metrics.horiBearingY,
+ doc = '''Top side bearing for horizontal layout.''' )
+
+ horiAdvance = property( lambda self: self._FT_Glyph_Metrics.horiAdvance,
+ doc = '''Advance width for horizontal layout.''' )
+
+ vertBearingX = property( lambda self: self._FT_Glyph_Metrics.vertBearingX,
+ doc = '''Left side bearing for vertical layout.''' )
+
+ vertBearingY = property( lambda self: self._FT_Glyph_Metrics.vertBearingY,
+ doc = '''Top side bearing for vertical layout. Larger positive values
+ mean further below the vertical glyph origin.''' )
+
+ vertAdvance = property( lambda self: self._FT_Glyph_Metrics.vertAdvance,
+ doc = '''Advance height for vertical layout. Positive values mean the
+ glyph has a positive advance downward.''' )
+
+
+# -----------------------------------------------------------------------------
+class SizeMetrics( object ):
+ '''
+ The size metrics structure gives the metrics of a size object.
+
+ **Note**
+
+ The scaling values, if relevant, are determined first during a size
+ changing operation. The remaining fields are then set by the driver. For
+ scalable formats, they are usually set to scaled values of the
+ corresponding fields in Face.
+
+ Note that due to glyph hinting, these values might not be exact for certain
+ fonts. Thus they must be treated as unreliable with an error margin of at
+ least one pixel!
+
+ Indeed, the only way to get the exact metrics is to render all glyphs. As
+ this would be a definite performance hit, it is up to client applications
+ to perform such computations.
+
+ The SizeMetrics structure is valid for bitmap fonts also.
+ '''
+
+ def __init__(self, metrics ):
+ '''
+ Create a new SizeMetrics object.
+
+ :param metrics: a FT_SizeMetrics
+ '''
+ self._FT_Size_Metrics = metrics
+
+ x_ppem = property( lambda self: self._FT_Size_Metrics.x_ppem,
+ doc = '''The width of the scaled EM square in pixels, hence the term
+ 'ppem' (pixels per EM). It is also referred to as 'nominal
+ width'.''' )
+
+ y_ppem = property( lambda self: self._FT_Size_Metrics.y_ppem,
+ doc = '''The height of the scaled EM square in pixels, hence the term
+ 'ppem' (pixels per EM). It is also referred to as 'nominal
+ height'.''' )
+
+ x_scale = property( lambda self: self._FT_Size_Metrics.x_scale,
+ doc = '''A 16.16 fractional scaling value used to convert horizontal
+ metrics from font units to 26.6 fractional pixels. Only
+ relevant for scalable font formats.''' )
+
+ y_scale = property( lambda self: self._FT_Size_Metrics.y_scale,
+ doc = '''A 16.16 fractional scaling value used to convert vertical
+ metrics from font units to 26.6 fractional pixels. Only
+ relevant for scalable font formats.''' )
+
+ ascender = property( lambda self: self._FT_Size_Metrics.ascender,
+ doc = '''The ascender in 26.6 fractional pixels. See Face for the
+ details.''' )
+
+ descender = property( lambda self: self._FT_Size_Metrics.descender,
+ doc = '''The descender in 26.6 fractional pixels. See Face for the
+ details.''' )
+
+ height = property( lambda self: self._FT_Size_Metrics.height,
+ doc = '''The height in 26.6 fractional pixels. See Face for the details.''' )
+
+ max_advance = property(lambda self: self._FT_Size_Metrics.max_advance,
+ doc = '''The maximal advance width in 26.6 fractional pixels. See
+ Face for the details.''' )
+
+
+
+# -----------------------------------------------------------------------------
+class BitmapSize( object ):
+ '''
+ FT_Bitmap_Size wrapper
+
+ This structure models the metrics of a bitmap strike (i.e., a set of glyphs
+ for a given point size and resolution) in a bitmap font. It is used for the
+ 'available_sizes' field of Face.
+
+ **Note**
+
+ Windows FNT: The nominal size given in a FNT font is not reliable. Thus
+ when the driver finds it incorrect, it sets 'size' to some calculated
+ values and sets 'x_ppem' and 'y_ppem' to the pixel width and height given
+ in the font, respectively.
+
+ TrueType embedded bitmaps: 'size', 'width', and 'height' values are not
+ contained in the bitmap strike itself. They are computed from the global
+ font parameters.
+ '''
+ def __init__(self, size ):
+ '''
+ Create a new SizeMetrics object.
+
+ :param size: a FT_Bitmap_Size
+ '''
+ self._FT_Bitmap_Size = size
+
+ height = property( lambda self: self._FT_Bitmap_Size.height,
+ doc = '''The vertical distance, in pixels, between two consecutive
+ baselines. It is always positive.''')
+
+ width = property( lambda self: self._FT_Bitmap_Size.width,
+ doc = '''The average width, in pixels, of all glyphs in the strike.''')
+
+ size = property( lambda self: self._FT_Bitmap_Size.size,
+ doc = '''The nominal size of the strike in 26.6 fractional points. This
+ field is not very useful.''')
+
+ x_ppem = property( lambda self: self._FT_Bitmap_Size.x_ppem,
+ doc = '''The horizontal ppem (nominal width) in 26.6 fractional
+ pixels.''')
+
+ y_ppem = property( lambda self: self._FT_Bitmap_Size.y_ppem,
+ doc = '''The vertical ppem (nominal width) in 26.6 fractional
+ pixels.''')
+
+
+# -----------------------------------------------------------------------------
+class Bitmap(object):
+ '''
+ FT_Bitmap wrapper
+
+ A structure used to describe a bitmap or pixmap to the raster. Note that we
+ now manage pixmaps of various depths through the 'pixel_mode' field.
+
+ *Note*:
+
+ For now, the only pixel modes supported by FreeType are mono and
+ grays. However, drivers might be added in the future to support more
+ 'colorful' options.
+ '''
+ def __init__(self, bitmap):
+ '''
+ Create a new Bitmap object.
+
+ :param bitmap: a FT_Bitmap
+ '''
+ self._FT_Bitmap = bitmap
+
+ rows = property(lambda self: self._FT_Bitmap.rows,
+ doc = '''The number of bitmap rows.''')
+
+ width = property(lambda self: self._FT_Bitmap.width,
+ doc = '''The number of pixels in bitmap row.''')
+
+ pitch = property(lambda self: self._FT_Bitmap.pitch,
+ doc = '''The pitch's absolute value is the number of bytes taken by one
+ bitmap row, including padding. However, the pitch is positive
+ when the bitmap has a 'down' flow, and negative when it has an
+ 'up' flow. In all cases, the pitch is an offset to add to a
+ bitmap pointer in order to go down one row.
+
+ Note that 'padding' means the alignment of a bitmap to a byte
+ border, and FreeType functions normally align to the smallest
+ possible integer value.
+
+ For the B/W rasterizer, 'pitch' is always an even number.
+
+ To change the pitch of a bitmap (say, to make it a multiple of
+ 4), use FT_Bitmap_Convert. Alternatively, you might use callback
+ functions to directly render to the application's surface; see
+ the file 'example2.py' in the tutorial for a demonstration.''')
+
+ def _get_buffer(self):
+ data = [self._FT_Bitmap.buffer[i] for i in range(self.rows*self.pitch)]
+ return data
+ buffer = property(_get_buffer,
+ doc = '''A typeless pointer to the bitmap buffer. This value should be
+ aligned on 32-bit boundaries in most cases.''')
+
+ num_grays = property(lambda self: self._FT_Bitmap.num_grays,
+ doc = '''This field is only used with FT_PIXEL_MODE_GRAY; it gives
+ the number of gray levels used in the bitmap.''')
+
+ pixel_mode = property(lambda self: self._FT_Bitmap.pixel_mode,
+ doc = '''The pixel mode, i.e., how pixel bits are stored. See
+ FT_Pixel_Mode for possible values.''')
+
+ palette_mode = property(lambda self: self._FT_Bitmap.palette_mode,
+ doc ='''This field is intended for paletted pixel modes; it
+ indicates how the palette is stored. Not used currently.''')
+
+ palette = property(lambda self: self._FT_Bitmap.palette,
+ doc = '''A typeless pointer to the bitmap palette; this field is
+ intended for paletted pixel modes. Not used currently.''')
+
+
+
+
+# -----------------------------------------------------------------------------
+class Charmap( object ):
+ '''
+ FT_Charmap wrapper.
+
+ A handle to a given character map. A charmap is used to translate character
+ codes in a given encoding into glyph indexes for its parent's face. Some
+ font formats may provide several charmaps per font.
+
+ Each face object owns zero or more charmaps, but only one of them can be
+ 'active' and used by FT_Get_Char_Index or FT_Load_Char.
+
+ The list of available charmaps in a face is available through the
+ 'face.num_charmaps' and 'face.charmaps' fields of FT_FaceRec.
+
+ The currently active charmap is available as 'face.charmap'. You should
+ call FT_Set_Charmap to change it.
+
+ **Note**:
+
+ When a new face is created (either through FT_New_Face or FT_Open_Face),
+ the library looks for a Unicode charmap within the list and automatically
+ activates it.
+
+ **See also**:
+
+ See FT_CharMapRec for the publicly accessible fields of a given character
+ map.
+ '''
+
+ def __init__( self, charmap ):
+ '''
+ Create a new Charmap object.
+
+ Parameters:
+ -----------
+ charmap : a FT_Charmap
+ '''
+ self._FT_Charmap = charmap
+
+ encoding = property( lambda self: self._FT_Charmap.contents.encoding,
+ doc = '''An FT_Encoding tag identifying the charmap. Use this with
+ FT_Select_Charmap.''')
+
+ platform_id = property( lambda self: self._FT_Charmap.contents.platform_id,
+ doc = '''An ID number describing the platform for the following
+ encoding ID. This comes directly from the TrueType
+ specification and should be emulated for other
+ formats.''')
+
+ encoding_id = property( lambda self: self._FT_Charmap.contents.encoding_id,
+ doc = '''A platform specific encoding number. This also comes from
+ the TrueType specification and should be emulated
+ similarly.''')
+
+ def _get_encoding_name(self):
+ encoding = self.encoding
+ for key,value in FT_ENCODINGS.items():
+ if encoding == value:
+ return key
+ return 'Unknown encoding'
+ encoding_name = property( _get_encoding_name,
+ doc = '''A platform specific encoding name. This also comes from
+ the TrueType specification and should be emulated
+ similarly.''')
+
+ def _get_index( self ):
+ return FT_Get_Charmap_Index( self._FT_Charmap )
+ index = property( _get_index,
+ doc = '''The index into the array of character maps within the face to
+ which 'charmap' belongs. If an error occurs, -1 is returned.''')
+
+ def _get_cmap_language_id( self ):
+ return FT_Get_CMap_Language_ID( self._FT_Charmap )
+ cmap_language_id = property( _get_cmap_language_id,
+ doc = '''The language ID of 'charmap'. If 'charmap' doesn't
+ belong to a TrueType/sfnt face, just return 0 as the
+ default value.''')
+
+ def _get_cmap_format( self ):
+ return FT_Get_CMap_Format( self._FT_Charmap )
+ cmap_format = property( _get_cmap_format,
+ doc = '''The format of 'charmap'. If 'charmap' doesn't belong to a
+ TrueType/sfnt face, return -1.''')
+
+
+
+# -----------------------------------------------------------------------------
+class Outline( object ):
+ '''
+ FT_Outline wrapper.
+
+ This structure is used to describe an outline to the scan-line converter.
+ '''
+ def __init__( self, outline ):
+ '''
+ Create a new Outline object.
+
+ :param charmap: a FT_Outline
+ '''
+ self._FT_Outline = outline
+
+ n_contours = property(lambda self: self._FT_Outline.n_contours)
+ def _get_contours(self):
+ n = self._FT_Outline.n_contours
+ data = [self._FT_Outline.contours[i] for i in range(n)]
+ return data
+ contours = property(_get_contours,
+ doc = '''The number of contours in the outline.''')
+
+ n_points = property(lambda self: self._FT_Outline.n_points)
+ def _get_points(self):
+ n = self._FT_Outline.n_points
+ data = []
+ for i in range(n):
+ v = self._FT_Outline.points[i]
+ data.append( (v.x,v.y) )
+ return data
+ points = property( _get_points,
+ doc = '''The number of points in the outline.''')
+
+ def _get_tags(self):
+ n = self._FT_Outline.n_points
+ data = [self._FT_Outline.tags[i] for i in range(n)]
+ return data
+ tags = property(_get_tags,
+ doc = '''A list of 'n_points' chars, giving each outline point's type.
+
+ If bit 0 is unset, the point is 'off' the curve, i.e., a Bezier
+ control point, while it is 'on' if set.
+
+ Bit 1 is meaningful for 'off' points only. If set, it indicates a
+ third-order Bezier arc control point; and a second-order control
+ point if unset.
+
+ If bit 2 is set, bits 5-7 contain the drop-out mode (as defined
+ in the OpenType specification; the value is the same as the
+ argument to the SCANMODE instruction).
+
+ Bits 3 and 4 are reserved for internal purposes.''')
+
+ flags = property(lambda self: self._FT_Outline.flags,
+ doc = '''A set of bit flags used to characterize the outline and give
+ hints to the scan-converter and hinter on how to
+ convert/grid-fit it. See FT_OUTLINE_FLAGS.''')
+
+ def get_inside_border( self ):
+ '''
+ Retrieve the FT_StrokerBorder value corresponding to the 'inside'
+ borders of a given outline.
+
+ :return: The border index. FT_STROKER_BORDER_RIGHT for empty or invalid
+ outlines.
+ '''
+ return FT_Outline_GetInsideBorder( self._FT_Outline )
+
+ def get_outside_border( self ):
+ '''
+ Retrieve the FT_StrokerBorder value corresponding to the 'outside'
+ borders of a given outline.
+
+ :return: The border index. FT_STROKER_BORDER_RIGHT for empty or invalid
+ outlines.
+ '''
+ return FT_Outline_GetInsideBorder( self._FT_Outline )
+
+ def get_bbox(self):
+ '''
+ Compute the exact bounding box of an outline. This is slower than
+ computing the control box. However, it uses an advanced algorithm which
+ returns very quickly when the two boxes coincide. Otherwise, the
+ outline Bezier arcs are traversed to extract their extrema.
+ '''
+ bbox = FT_BBox()
+ error = FT_Outline_Get_BBox(byref(self._FT_Outline), byref(bbox))
+ if error: raise FT_Exception(error)
+ return bbox
+
+ def get_cbox(self):
+ '''
+ Return an outline's 'control box'. The control box encloses all the
+ outline's points, including Bezier control points. Though it coincides
+ with the exact bounding box for most glyphs, it can be slightly larger
+ in some situations (like when rotating an outline which contains Bezier
+ outside arcs).
+
+ Computing the control box is very fast, while getting the bounding box
+ can take much more time as it needs to walk over all segments and arcs
+ in the outline. To get the latter, you can use the 'ftbbox' component
+ which is dedicated to this single task.
+ '''
+ bbox = FT_BBox()
+ error = FT_Outline_Get_CBox(byref(self._FT_Outline), byref(bbox))
+ if error: raise FT_Exception(error)
+ return BBox(bbox)
+
+
+
+
+# -----------------------------------------------------------------------------
+class Glyph( object ):
+ '''
+ FT_Glyph wrapper.
+
+ The root glyph structure contains a given glyph image plus its advance
+ width in 16.16 fixed float format.
+ '''
+ def __init__( self, glyph ):
+ '''
+ Create Glyph object from an FT glyph.
+
+ :param glyph: valid FT_Glyph object
+ '''
+ self._FT_Glyph = glyph
+
+ def __del__( self ):
+ '''
+ Destroy glyph.
+ '''
+ FT_Done_Glyph( self._FT_Glyph )
+
+ def _get_format( self ):
+ return self._FT_Glyph.contents.format
+ format = property( _get_format,
+ doc = '''The format of the glyph's image.''')
+
+
+ def stroke( self, stroker, destroy=False ):
+ '''
+ Stroke a given outline glyph object with a given stroker.
+
+ :param stroker: A stroker handle.
+
+ :param destroy: A Boolean. If 1, the source glyph object is destroyed on
+ success.
+
+ **Note**:
+
+ The source glyph is untouched in case of error.
+ '''
+ error = FT_Glyph_Stroke( byref(self._FT_Glyph),
+ stroker._FT_Stroker, destroy )
+ if error: raise FT_Exception( error )
+
+ def to_bitmap( self, mode, origin, destroy=False ):
+ '''
+ Convert a given glyph object to a bitmap glyph object.
+
+ :param mode: An enumeration that describes how the data is rendered.
+
+ :param origin: A pointer to a vector used to translate the glyph image
+ before rendering. Can be 0 (if no translation). The origin is
+ expressed in 26.6 pixels.
+
+ :param destroy: A boolean that indicates that the original glyph image
+ should be destroyed by this function. It is never destroyed
+ in case of error.
+
+ **Note**:
+
+ This function does nothing if the glyph format isn't scalable.
+
+ The glyph image is translated with the 'origin' vector before
+ rendering.
+
+ The first parameter is a pointer to an FT_Glyph handle, that will be
+ replaced by this function (with newly allocated data). Typically, you
+ would use (omitting error handling):
+ '''
+ error = FT_Glyph_To_Bitmap( byref(self._FT_Glyph),
+ mode, origin, destroy)
+ if error: raise FT_Exception( error )
+ return BitmapGlyph( self._FT_Glyph )
+
+ def get_cbox(self, bbox_mode):
+ '''
+ Return an outline's 'control box'. The control box encloses all the
+ outline's points, including Bezier control points. Though it coincides
+ with the exact bounding box for most glyphs, it can be slightly larger
+ in some situations (like when rotating an outline which contains Bezier
+ outside arcs).
+
+ Computing the control box is very fast, while getting the bounding box
+ can take much more time as it needs to walk over all segments and arcs
+ in the outline. To get the latter, you can use the 'ftbbox' component
+ which is dedicated to this single task.
+
+ :param mode: The mode which indicates how to interpret the returned
+ bounding box values.
+
+ **Note**:
+
+ Coordinates are relative to the glyph origin, using the y upwards
+ convention.
+
+ If the glyph has been loaded with FT_LOAD_NO_SCALE, 'bbox_mode' must be
+ set to FT_GLYPH_BBOX_UNSCALED to get unscaled font units in 26.6 pixel
+ format. The value FT_GLYPH_BBOX_SUBPIXELS is another name for this
+ constant.
+
+ Note that the maximum coordinates are exclusive, which means that one
+ can compute the width and height of the glyph image (be it in integer
+ or 26.6 pixels) as:
+
+ width = bbox.xMax - bbox.xMin;
+ height = bbox.yMax - bbox.yMin;
+
+ Note also that for 26.6 coordinates, if 'bbox_mode' is set to
+ FT_GLYPH_BBOX_GRIDFIT, the coordinates will also be grid-fitted, which
+ corresponds to:
+
+ bbox.xMin = FLOOR(bbox.xMin);
+ bbox.yMin = FLOOR(bbox.yMin);
+ bbox.xMax = CEILING(bbox.xMax);
+ bbox.yMax = CEILING(bbox.yMax);
+
+ To get the bbox in pixel coordinates, set 'bbox_mode' to
+ FT_GLYPH_BBOX_TRUNCATE.
+
+ To get the bbox in grid-fitted pixel coordinates, set 'bbox_mode' to
+ FT_GLYPH_BBOX_PIXELS.
+ '''
+ bbox = FT_BBox()
+ error = FT_Glyph_Get_CBox(byref(self._FT_Glyph), bbox_mode,byref(bbox))
+ if error: raise FT_Exception(error)
+ return BBox(bbox)
+
+
+
+# -----------------------------------------------------------------------------
+class BitmapGlyph( object ):
+ '''
+ FT_BitmapGlyph wrapper.
+
+ A structure used for bitmap glyph images. This really is a 'sub-class' of
+ FT_GlyphRec.
+ '''
+ def __init__( self, glyph ):
+ '''
+ Create Glyph object from an FT glyph.
+
+ Parameters:
+ -----------
+ glyph: valid FT_Glyph object
+ '''
+ self._FT_BitmapGlyph = cast(glyph, FT_BitmapGlyph)
+
+ # def __del__( self ):
+ # '''
+ # Destroy glyph.
+ # '''
+ # FT_Done_Glyph( cast(self._FT_BitmapGlyph, FT_Glyph) )
+
+
+ def _get_format( self ):
+ return self._FT_BitmapGlyph.contents.format
+ format = property( _get_format,
+ doc = '''The format of the glyph's image.''')
+
+
+ def _get_bitmap( self ):
+ return Bitmap( self._FT_BitmapGlyph.contents.bitmap )
+ bitmap = property( _get_bitmap,
+ doc = '''A descriptor for the bitmap.''')
+
+
+ def _get_left( self ):
+ return self._FT_BitmapGlyph.contents.left
+ left = property( _get_left,
+ doc = '''The left-side bearing, i.e., the horizontal distance from the
+ current pen position to the left border of the glyph bitmap.''')
+
+
+ def _get_top( self ):
+ return self._FT_BitmapGlyph.contents.top
+ top = property( _get_top,
+ doc = '''The top-side bearing, i.e., the vertical distance from the
+ current pen position to the top border of the glyph bitmap.
+ This distance is positive for upwards y!''')
+
+
+# -----------------------------------------------------------------------------
+class GlyphSlot( object ):
+ '''
+ FT_GlyphSlot wrapper.
+
+ FreeType root glyph slot class structure. A glyph slot is a container where
+ individual glyphs can be loaded, be they in outline or bitmap format.
+ '''
+
+ def __init__( self, slot ):
+ '''
+ Create GlyphSlot object from an FT glyph slot.
+
+ Parameters:
+ -----------
+ glyph: valid FT_GlyphSlot object
+ '''
+ self._FT_GlyphSlot = slot
+
+ def get_glyph( self ):
+ '''
+ A function used to extract a glyph image from a slot. Note that the
+ created FT_Glyph object must be released with FT_Done_Glyph.
+ '''
+ aglyph = FT_Glyph()
+ error = FT_Get_Glyph( self._FT_GlyphSlot, byref(aglyph) )
+ if error: raise FT_Exception( error )
+ return Glyph( aglyph )
+
+ def _get_bitmap( self ):
+ return Bitmap( self._FT_GlyphSlot.contents.bitmap )
+ bitmap = property( _get_bitmap,
+ doc = '''This field is used as a bitmap descriptor when the slot format
+ is FT_GLYPH_FORMAT_BITMAP. Note that the address and content of
+ the bitmap buffer can change between calls of FT_Load_Glyph and
+ a few other functions.''')
+
+ def _get_metrics( self ):
+ return GlyphMetrics( self._FT_GlyphSlot.contents.metrics )
+ metrics = property( _get_metrics,
+ doc = '''The metrics of the last loaded glyph in the slot. The returned
+ values depend on the last load flags (see the FT_Load_Glyph API
+ function) and can be expressed either in 26.6 fractional pixels or font
+ units. Note that even when the glyph image is transformed, the metrics
+ are not.''')
+
+ def _get_next( self ):
+ return GlyphSlot( self._FT_GlyphSlot.contents.next )
+ next = property( _get_next,
+ doc = '''In some cases (like some font tools), several glyph slots per
+ face object can be a good thing. As this is rare, the glyph slots
+ are listed through a direct, single-linked list using its 'next'
+ field.''')
+
+ advance = property( lambda self: self._FT_GlyphSlot.contents.advance,
+ doc = '''This shorthand is, depending on FT_LOAD_IGNORE_TRANSFORM, the
+ transformed advance width for the glyph (in 26.6 fractional
+ pixel format). As specified with FT_LOAD_VERTICAL_LAYOUT, it
+ uses either the 'horiAdvance' or the 'vertAdvance' value of
+ 'metrics' field.''')
+
+ def _get_outline( self ):
+ return Outline( self._FT_GlyphSlot.contents.outline )
+ outline = property( _get_outline,
+ doc = '''The outline descriptor for the current glyph image if its
+ format is FT_GLYPH_FORMAT_OUTLINE. Once a glyph is loaded,
+ 'outline' can be transformed, distorted, embolded,
+ etc. However, it must not be freed.''')
+
+ format = property( lambda self: self._FT_GlyphSlot.contents.format,
+ doc = '''This field indicates the format of the image contained in the
+ glyph slot. Typically FT_GLYPH_FORMAT_BITMAP,
+ FT_GLYPH_FORMAT_OUTLINE, or FT_GLYPH_FORMAT_COMPOSITE, but
+ others are possible.''')
+
+ bitmap_top = property( lambda self:
+ self._FT_GlyphSlot.contents.bitmap_top,
+ doc = '''This is the bitmap's top bearing expressed in integer
+ pixels. Remember that this is the distance from the
+ baseline to the top-most glyph scanline, upwards y
+ coordinates being positive.''')
+
+ bitmap_left = property( lambda self:
+ self._FT_GlyphSlot.contents.bitmap_left,
+ doc = '''This is the bitmap's left bearing expressed in integer
+ pixels. Of course, this is only valid if the format is
+ FT_GLYPH_FORMAT_BITMAP.''')
+
+ linearHoriAdvance = property( lambda self:
+ self._FT_GlyphSlot.contents.linearHoriAdvance,
+ doc = '''The advance width of the unhinted glyph. Its value
+ is expressed in 16.16 fractional pixels, unless
+ FT_LOAD_LINEAR_DESIGN is set when loading the glyph.
+ This field can be important to perform correct
+ WYSIWYG layout. Only relevant for outline glyphs.''')
+
+ linearVertAdvance = property( lambda self:
+ self._FT_GlyphSlot.contents.linearVertAdvance,
+ doc = '''The advance height of the unhinted glyph. Its value
+ is expressed in 16.16 fractional pixels, unless
+ FT_LOAD_LINEAR_DESIGN is set when loading the glyph.
+ This field can be important to perform correct
+ WYSIWYG layout. Only relevant for outline glyphs.''')
+
+
+# -----------------------------------------------------------------------------
+# Face wrapper
+# -----------------------------------------------------------------------------
+class Face( object ):
+ '''
+ FT_Face wrapper
+
+ FreeType root face class structure. A face object models a typeface in a
+ font file.
+ '''
+ def __init__( self, filename, index = 0 ):
+ '''
+ Build a new Face
+
+ :param str filename:
+ A path to the font file.
+
+ :param int index:
+ The index of the face within the font.
+ The first face has index 0.
+ '''
+ library = get_handle( )
+ face = FT_Face( )
+ self._FT_Face = None
+ #error = FT_New_Face( library, filename, 0, byref(face) )
+ self._filebodys = []
+ try:
+ u_filename = c_char_p(_encode_filename(filename))
+ error = FT_New_Face( library, u_filename, index, byref(face) )
+ except UnicodeError:
+ with open(filename, mode='rb') as f:
+ filebody = f.read()
+ error = FT_New_Memory_Face( library, filebody, len(filebody),
+ index, byref(face) )
+ self._filebodys.append(filebody) # prevent gc
+ if error: raise FT_Exception( error )
+ self._filename = filename
+ self._index = index
+ self._FT_Face = face
+
+ def __del__( self ):
+ '''
+ Discard face object, as well as all of its child slots and sizes.
+ '''
+ if self._FT_Face is not None:
+ FT_Done_Face( self._FT_Face )
+
+
+ def attach_file( self, filename ):
+ '''
+ Attach data to a face object. Normally, this is used to read
+ additional information for the face object. For example, you can attach
+ an AFM file that comes with a Type 1 font to get the kerning values and
+ other metrics.
+
+ :param filename: Filename to attach
+
+ **Note**
+
+ The meaning of the 'attach' (i.e., what really happens when the new
+ file is read) is not fixed by FreeType itself. It really depends on the
+ font format (and thus the font driver).
+
+ Client applications are expected to know what they are doing when
+ invoking this function. Most drivers simply do not implement file
+ attachments.
+ '''
+
+ try:
+ u_filename = c_char_p(_encode_filename(filename))
+ error = FT_Attach_File( self._FT_Face, u_filename )
+ except UnicodeError:
+ with open(filename, mode='rb') as f:
+ filebody = f.read()
+ parameters = FT_Open_Args()
+ parameters.flags = FT_OPEN_MEMORY
+ parameters.memory_base = filebody
+ parameters.memory_size = len(filebody)
+ parameters.stream = None
+ error = FT_Attach_Stream( self._FT_Face, parameters )
+ self._filebodys.append(filebody) # prevent gc
+ if error: raise FT_Exception( error)
+
+
+ def set_char_size( self, width=0, height=0, hres=72, vres=72 ):
+ '''
+ This function calls FT_Request_Size to request the nominal size (in
+ points).
+
+ :param float width: The nominal width, in 26.6 fractional points.
+
+ :param float height: The nominal height, in 26.6 fractional points.
+
+ :param float hres: The horizontal resolution in dpi.
+
+ :param float vres: The vertical resolution in dpi.
+
+ **Note**
+
+ If either the character width or height is zero, it is set equal to the
+ other value.
+
+ If either the horizontal or vertical resolution is zero, it is set
+ equal to the other value.
+
+ A character width or height smaller than 1pt is set to 1pt; if both
+ resolution values are zero, they are set to 72dpi.
+
+ Don't use this function if you are using the FreeType cache API.
+ '''
+ error = FT_Set_Char_Size( self._FT_Face, width, height, hres, vres )
+ if error: raise FT_Exception( error)
+
+ def set_pixel_sizes( self, width, height ):
+ '''
+ This function calls FT_Request_Size to request the nominal size (in
+ pixels).
+
+ :param width: The nominal width, in pixels.
+
+ :param height: The nominal height, in pixels.
+ '''
+ error = FT_Set_Pixel_Sizes( self._FT_Face, width, height )
+ if error: raise FT_Exception(error)
+
+ def select_charmap( self, encoding ):
+ '''
+ Select a given charmap by its encoding tag (as listed in 'freetype.h').
+
+ **Note**:
+
+ This function returns an error if no charmap in the face corresponds to
+ the encoding queried here.
+
+ Because many fonts contain more than a single cmap for Unicode
+ encoding, this function has some special code to select the one which
+ covers Unicode best ('best' in the sense that a UCS-4 cmap is preferred
+ to a UCS-2 cmap). It is thus preferable to FT_Set_Charmap in this case.
+ '''
+ error = FT_Select_Charmap( self._FT_Face, encoding )
+ if error: raise FT_Exception(error)
+
+ def set_charmap( self, charmap ):
+ '''
+ Select a given charmap for character code to glyph index mapping.
+
+ :param charmap: A handle to the selected charmap.
+ '''
+ error = FT_Set_Charmap( self._FT_Face, charmap._FT_Charmap )
+ if error : raise FT_Exception(error)
+
+ def get_char_index( self, charcode ):
+ '''
+ Return the glyph index of a given character code. This function uses a
+ charmap object to do the mapping.
+
+ :param charcode: The character code.
+
+ **Note**:
+
+ If you use FreeType to manipulate the contents of font files directly,
+ be aware that the glyph index returned by this function doesn't always
+ correspond to the internal indices used within the file. This is done
+ to ensure that value 0 always corresponds to the 'missing glyph'.
+ '''
+ if isinstance(charcode, (str,unicode)):
+ charcode = ord(charcode)
+ return FT_Get_Char_Index( self._FT_Face, charcode )
+
+ def get_first_char( self ):
+ '''
+ This function is used to return the first character code in the current
+ charmap of a given face. It also returns the corresponding glyph index.
+
+ :return: Glyph index of first character code. 0 if charmap is empty.
+
+ **Note**:
+
+ You should use this function with get_next_char to be able to parse
+ all character codes available in a given charmap. The code should look
+ like this:
+
+ Note that 'agindex' is set to 0 if the charmap is empty. The result
+ itself can be 0 in two cases: if the charmap is empty or if the value 0
+ is the first valid character code.
+ '''
+ agindex = FT_UInt()
+ charcode = FT_Get_First_Char( self._FT_Face, byref(agindex) )
+ return charcode, agindex.value
+
+ def get_next_char( self, charcode, agindex ):
+ '''
+ This function is used to return the next character code in the current
+ charmap of a given face following the value 'charcode', as well as the
+ corresponding glyph index.
+
+ :param charcode: The starting character code.
+
+ :param agindex: Glyph index of next character code. 0 if charmap is empty.
+
+ **Note**:
+
+ You should use this function with FT_Get_First_Char to walk over all
+ character codes available in a given charmap. See the note for this
+ function for a simple code example.
+
+ Note that 'agindex' is set to 0 when there are no more codes in the
+ charmap.
+ '''
+ agindex = FT_UInt( 0 ) #agindex )
+ charcode = FT_Get_Next_Char( self._FT_Face, charcode, byref(agindex) )
+ return charcode, agindex.value
+
+ def get_name_index( self, name ):
+ '''
+ Return the glyph index of a given glyph name. This function uses driver
+ specific objects to do the translation.
+
+ :param name: The glyph name.
+ '''
+ return FT_Get_Name_Index( self._FT_Face, name )
+
+ def set_transform( self, matrix, delta ):
+ '''
+ A function used to set the transformation that is applied to glyph
+ images when they are loaded into a glyph slot through FT_Load_Glyph.
+
+ :param matrix: A pointer to the transformation's 2x2 matrix.
+ Use 0 for the identity matrix.
+
+ :parm delta: A pointer to the translation vector.
+ Use 0 for the null vector.
+
+ **Note**:
+
+ The transformation is only applied to scalable image formats after the
+ glyph has been loaded. It means that hinting is unaltered by the
+ transformation and is performed on the character size given in the last
+ call to FT_Set_Char_Size or FT_Set_Pixel_Sizes.
+
+ Note that this also transforms the 'face.glyph.advance' field, but
+ not the values in 'face.glyph.metrics'.
+ '''
+ FT_Set_Transform( self._FT_Face,
+ byref(matrix), byref(delta) )
+
+ def select_size( self, strike_index ):
+ '''
+ Select a bitmap strike.
+
+ :param strike_index: The index of the bitmap strike in the
+ 'available_sizes' field of Face object.
+ '''
+ error = FT_Select_Size( self._FT_Face, strike_index )
+ if error: raise FT_Exception( error )
+
+ def load_glyph( self, index, flags = FT_LOAD_RENDER ):
+ '''
+ A function used to load a single glyph into the glyph slot of a face
+ object.
+
+ :param index: The index of the glyph in the font file. For CID-keyed
+ fonts (either in PS or in CFF format) this argument
+ specifies the CID value.
+
+ :param flags: A flag indicating what to load for this glyph. The FT_LOAD_XXX
+ constants can be used to control the glyph loading process
+ (e.g., whether the outline should be scaled, whether to load
+ bitmaps or not, whether to hint the outline, etc).
+
+ **Note**:
+
+ The loaded glyph may be transformed. See FT_Set_Transform for the
+ details.
+
+ For subsetted CID-keyed fonts, 'FT_Err_Invalid_Argument' is returned
+ for invalid CID values (this is, for CID values which don't have a
+ corresponding glyph in the font). See the discussion of the
+ FT_FACE_FLAG_CID_KEYED flag for more details.
+ '''
+ error = FT_Load_Glyph( self._FT_Face, index, flags )
+ if error: raise FT_Exception( error )
+
+ def load_char( self, char, flags = FT_LOAD_RENDER ):
+ '''
+ A function used to load a single glyph into the glyph slot of a face
+ object, according to its character code.
+
+ :param char: The glyph's character code, according to the current
+ charmap used in the face.
+
+ :param flags: A flag indicating what to load for this glyph. The
+ FT_LOAD_XXX constants can be used to control the glyph
+ loading process (e.g., whether the outline should be
+ scaled, whether to load bitmaps or not, whether to hint
+ the outline, etc).
+
+ **Note**:
+
+ This function simply calls FT_Get_Char_Index and FT_Load_Glyph.
+ '''
+
+ if len(char) == 1:
+ char = ord(char)
+ error = FT_Load_Char( self._FT_Face, char, flags )
+ if error: raise FT_Exception( error )
+
+
+ def get_advance( self, gindex, flags ):
+ '''
+ Retrieve the advance value of a given glyph outline in an FT_Face. By
+ default, the unhinted advance is returned in font units.
+
+ :param gindex: The glyph index.
+
+ :param flags: A set of bit flags similar to those used when calling
+ FT_Load_Glyph, used to determine what kind of advances
+ you need.
+
+ :return: The advance value, in either font units or 16.16 format.
+
+ If FT_LOAD_VERTICAL_LAYOUT is set, this is the vertical
+ advance corresponding to a vertical layout. Otherwise, it is
+ the horizontal advance in a horizontal layout.
+ '''
+
+ padvance = FT_Fixed(0)
+ error = FT_Get_Advance( self._FT_Face, gindex, flags, byref(padvance) )
+ if error: raise FT_Exception( error )
+ return padvance.value
+
+
+
+ def get_kerning( self, left, right, mode = FT_KERNING_DEFAULT ):
+ '''
+ Return the kerning vector between two glyphs of a same face.
+
+ :param left: The index of the left glyph in the kern pair.
+
+ :param right: The index of the right glyph in the kern pair.
+
+ :param mode: See FT_Kerning_Mode for more information. Determines the scale
+ and dimension of the returned kerning vector.
+
+ **Note**:
+
+ Only horizontal layouts (left-to-right & right-to-left) are supported
+ by this method. Other layouts, or more sophisticated kernings, are out
+ of the scope of this API function -- they can be implemented through
+ format-specific interfaces.
+ '''
+ left_glyph = self.get_char_index( left )
+ right_glyph = self.get_char_index( right )
+ kerning = FT_Vector(0,0)
+ error = FT_Get_Kerning( self._FT_Face,
+ left_glyph, right_glyph, mode, byref(kerning) )
+ if error: raise FT_Exception( error )
+ return kerning
+
+ def get_format(self):
+ '''
+ Return a string describing the format of a given face, using values
+ which can be used as an X11 FONT_PROPERTY. Possible values are
+ 'TrueType', 'Type 1', 'BDF', ‘PCF', ‘Type 42', ‘CID Type 1', ‘CFF',
+ 'PFR', and ‘Windows FNT'.
+ '''
+
+ return FT_Get_X11_Font_Format( self._FT_Face )
+
+
+ def get_fstype(self):
+ '''
+ Return the fsType flags for a font (embedding permissions).
+
+ The return value is a tuple containing the freetype enum name
+ as a string and the actual flag as an int
+ '''
+
+ flag = FT_Get_FSType_Flags( self._FT_Face )
+ for k, v in FT_FSTYPE_XXX.items():
+ if v == flag:
+ return k, v
+
+
+ def _get_sfnt_name_count(self):
+ return FT_Get_Sfnt_Name_Count( self._FT_Face )
+ sfnt_name_count = property(_get_sfnt_name_count,
+ doc = '''Number of name strings in the SFNT 'name' table.''')
+
+ def get_sfnt_name( self, index ):
+ '''
+ Retrieve a string of the SFNT 'name' table for a given index
+
+ :param index: The index of the 'name' string.
+
+ **Note**:
+
+ The 'string' array returned in the 'aname' structure is not
+ null-terminated. The application should deallocate it if it is no
+ longer in use.
+
+ Use FT_Get_Sfnt_Name_Count to get the total number of available
+ 'name' table entries, then do a loop until you get the right
+ platform, encoding, and name ID.
+ '''
+ name = FT_SfntName( )
+ error = FT_Get_Sfnt_Name( self._FT_Face, index, byref(name) )
+ if error: raise FT_Exception( error )
+ return SfntName( name )
+
+ def _get_postscript_name( self ):
+ return FT_Get_Postscript_Name( self._FT_Face )
+ postscript_name = property( _get_postscript_name,
+ doc = '''ASCII PostScript name of face, if available. This only
+ works with PostScript and TrueType fonts.''')
+
+ def _has_horizontal( self ):
+ return bool( self.face_flags & FT_FACE_FLAG_HORIZONTAL )
+ has_horizontal = property( _has_horizontal,
+ doc = '''True whenever a face object contains horizontal metrics
+ (this is true for all font formats though).''')
+
+ def _has_vertical( self ):
+ return bool( self.face_flags & FT_FACE_FLAG_VERTICAL )
+ has_vertical = property( _has_vertical,
+ doc = '''True whenever a face object contains vertical metrics.''')
+
+ def _has_kerning( self ):
+ return bool( self.face_flags & FT_FACE_FLAG_KERNING )
+ has_kerning = property( _has_kerning,
+ doc = '''True whenever a face object contains kerning data that can
+ be accessed with FT_Get_Kerning.''')
+
+ def _is_scalable( self ):
+ return bool( self.face_flags & FT_FACE_FLAG_SCALABLE )
+ is_scalable = property( _is_scalable,
+ doc = '''true whenever a face object contains a scalable font face
+ (true for TrueType, Type 1, Type 42, CID, OpenType/CFF,
+ and PFR font formats.''')
+
+ def _is_sfnt( self ):
+ return bool( self.face_flags & FT_FACE_FLAG_SFNT )
+ is_sfnt = property( _is_sfnt,
+ doc = '''true whenever a face object contains a font whose format is
+ based on the SFNT storage scheme. This usually means: TrueType
+ fonts, OpenType fonts, as well as SFNT-based embedded bitmap
+ fonts.
+
+ If this macro is true, all functions defined in
+ FT_SFNT_NAMES_H and FT_TRUETYPE_TABLES_H are available.''')
+
+ def _is_fixed_width( self ):
+ return bool( self.face_flags & FT_FACE_FLAG_FIXED_WIDTH )
+ is_fixed_width = property( _is_fixed_width,
+ doc = '''True whenever a face object contains a font face that
+ contains fixed-width (or 'monospace', 'fixed-pitch',
+ etc.) glyphs.''')
+
+ def _has_fixed_sizes( self ):
+ return bool( self.face_flags & FT_FACE_FLAG_FIXED_SIZES )
+ has_fixed_sizes = property( _has_fixed_sizes,
+ doc = '''True whenever a face object contains some embedded
+ bitmaps. See the 'available_sizes' field of the FT_FaceRec
+ structure.''')
+
+ def _has_glyph_names( self ):
+ return bool( self.face_flags & FT_FACE_FLAG_GLYPH_NAMES )
+ has_glyph_names = property( _has_glyph_names,
+ doc = '''True whenever a face object contains some glyph names
+ that can be accessed through FT_Get_Glyph_Name.''')
+
+ def _has_multiple_masters( self ):
+ return bool( self.face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS )
+ has_multiple_masters = property( _has_multiple_masters,
+ doc = '''True whenever a face object contains some
+ multiple masters. The functions provided by
+ FT_MULTIPLE_MASTERS_H are then available to
+ choose the exact design you want.''')
+
+ def _is_cid_keyed( self ):
+ return bool( self.face_flags & FT_FACE_FLAG_CID_KEYED )
+ is_cid_keyed = property( _is_cid_keyed,
+ doc = '''True whenever a face object contains a CID-keyed
+ font. See the discussion of FT_FACE_FLAG_CID_KEYED for
+ more details.
+
+ If this macro is true, all functions defined in FT_CID_H
+ are available.''')
+
+ def _is_tricky( self ):
+ return bool( self.face_flags & FT_FACE_FLAG_TRICKY )
+ is_tricky = property( _is_tricky,
+ doc = '''True whenever a face represents a 'tricky' font. See the
+ discussion of FT_FACE_FLAG_TRICKY for more details.''')
+
+
+ num_faces = property(lambda self: self._FT_Face.contents.num_faces,
+ doc = '''The number of faces in the font file. Some font formats can
+ have multiple faces in a font file.''')
+
+ face_index = property(lambda self: self._FT_Face.contents.face_index,
+ doc = '''The index of the face in the font file. It is set to 0 if
+ there is only one face in the font file.''')
+
+ face_flags = property(lambda self: self._FT_Face.contents.face_flags,
+ doc = '''A set of bit flags that give important information about
+ the face; see FT_FACE_FLAG_XXX for the details.''')
+
+ style_flags = property(lambda self: self._FT_Face.contents.style_flags,
+ doc = '''A set of bit flags indicating the style of the face; see
+ FT_STYLE_FLAG_XXX for the details.''')
+
+ num_glyphs = property(lambda self: self._FT_Face.contents.num_glyphs,
+ doc = '''The number of glyphs in the face. If the face is scalable
+ and has sbits (see 'num_fixed_sizes'), it is set to the number of
+ outline glyphs.
+
+ For CID-keyed fonts, this value gives the highest CID used in the
+ font.''')
+
+ family_name = property(lambda self: self._FT_Face.contents.family_name,
+ doc = '''The face's family name. This is an ASCII string, usually
+ in English, which describes the typeface's family (like
+ 'Times New Roman', 'Bodoni', 'Garamond', etc). This is a
+ least common denominator used to list fonts. Some formats
+ (TrueType & OpenType) provide localized and Unicode
+ versions of this string. Applications should use the
+ format specific interface to access them. Can be NULL
+ (e.g., in fonts embedded in a PDF file).''')
+
+ style_name = property(lambda self: self._FT_Face.contents.style_name,
+ doc = '''The face's style name. This is an ASCII string, usually in
+ English, which describes the typeface's style (like
+ 'Italic', 'Bold', 'Condensed', etc). Not all font formats
+ provide a style name, so this field is optional, and can be
+ set to NULL. As for 'family_name', some formats provide
+ localized and Unicode versions of this string. Applications
+ should use the format specific interface to access them.''')
+
+ num_fixed_sizes = property(lambda self: self._FT_Face.contents.num_fixed_sizes,
+ doc = '''The number of bitmap strikes in the face. Even if the
+ face is scalable, there might still be bitmap strikes,
+ which are called 'sbits' in that case.''')
+
+ def _get_available_sizes( self ):
+ sizes = []
+ n = self.num_fixed_sizes
+ FT_sizes = self._FT_Face.contents.available_sizes
+ for i in range(n):
+ sizes.append( BitmapSize(FT_sizes[i]) )
+ return sizes
+ available_sizes = property(_get_available_sizes,
+ doc = '''A list of FT_Bitmap_Size for all bitmap strikes in the
+ face. It is set to NULL if there is no bitmap strike.''')
+
+ num_charmaps = property(lambda self: self._FT_Face.contents.num_charmaps)
+ def _get_charmaps( self ):
+ charmaps = []
+ n = self._FT_Face.contents.num_charmaps
+ FT_charmaps = self._FT_Face.contents.charmaps
+ for i in range(n):
+ charmaps.append( Charmap(FT_charmaps[i]) )
+ return charmaps
+ charmaps = property(_get_charmaps,
+ doc = '''A list of the charmaps of the face.''')
+
+ # ('generic', FT_Generic),
+
+ def _get_bbox( self ):
+ return BBox( self._FT_Face.contents.bbox )
+ bbox = property( _get_bbox,
+ doc = '''The font bounding box. Coordinates are expressed in font units
+ (see 'units_per_EM'). The box is large enough to contain any
+ glyph from the font. Thus, 'bbox.yMax' can be seen as the
+ 'maximal ascender', and 'bbox.yMin' as the 'minimal
+ descender'. Only relevant for scalable formats.
+
+ Note that the bounding box might be off by (at least) one pixel
+ for hinted fonts. See FT_Size_Metrics for further discussion.''')
+
+ units_per_EM = property(lambda self: self._FT_Face.contents.units_per_EM,
+ doc = '''The number of font units per EM square for this
+ face. This is typically 2048 for TrueType fonts, and 1000
+ for Type 1 fonts. Only relevant for scalable formats.''')
+
+ ascender = property(lambda self: self._FT_Face.contents.ascender,
+ doc = '''The typographic ascender of the face, expressed in font
+ units. For font formats not having this information, it is
+ set to 'bbox.yMax'. Only relevant for scalable formats.''')
+
+ descender = property(lambda self: self._FT_Face.contents.descender,
+ doc = '''The typographic descender of the face, expressed in font
+ units. For font formats not having this information, it is
+ set to 'bbox.yMin'. Note that this field is usually
+ negative. Only relevant for scalable formats.''')
+
+ height = property(lambda self: self._FT_Face.contents.height,
+ doc = '''The height is the vertical distance between two consecutive
+ baselines, expressed in font units. It is always positive. Only
+ relevant for scalable formats.''')
+
+ max_advance_width = property(lambda self: self._FT_Face.contents.max_advance_width,
+ doc = '''The maximal advance width, in font units, for all
+ glyphs in this face. This can be used to make word
+ wrapping computations faster. Only relevant for
+ scalable formats.''')
+
+ max_advance_height = property(lambda self: self._FT_Face.contents.max_advance_height,
+ doc = '''The maximal advance height, in font units, for all
+ glyphs in this face. This is only relevant for
+ vertical layouts, and is set to 'height' for fonts
+ that do not provide vertical metrics. Only relevant
+ for scalable formats.''')
+
+ underline_position = property(lambda self: self._FT_Face.contents.underline_position,
+ doc = '''The position, in font units, of the underline line
+ for this face. It is the center of the underlining
+ stem. Only relevant for scalable formats.''')
+
+ underline_thickness = property(lambda self: self._FT_Face.contents.underline_thickness,
+ doc = '''The thickness, in font units, of the underline for
+ this face. Only relevant for scalable formats.''')
+
+
+ def _get_glyph( self ):
+ return GlyphSlot( self._FT_Face.contents.glyph )
+ glyph = property( _get_glyph,
+ doc = '''The face's associated glyph slot(s).''')
+
+ def _get_size( self ):
+ size = self._FT_Face.contents.size
+ metrics = size.contents.metrics
+ return SizeMetrics(metrics)
+ size = property( _get_size,
+ doc = '''The current active size for this face.''')
+
+ def _get_charmap( self ):
+ return Charmap( self._FT_Face.contents.charmap)
+ charmap = property( _get_charmap,
+ doc = '''The current active charmap for this face.''')
+
+
+
+# -----------------------------------------------------------------------------
+# SfntName wrapper
+# -----------------------------------------------------------------------------
+class SfntName( object ):
+ '''
+ SfntName wrapper
+
+ A structure used to model an SFNT 'name' table entry.
+ '''
+ def __init__(self, name):
+ '''
+ Create a new SfntName object.
+
+ :param name : SFNT 'name' table entry.
+
+ '''
+ self._FT_SfntName = name
+
+ platform_id = property(lambda self: self._FT_SfntName.platform_id,
+ doc = '''The platform ID for 'string'.''')
+
+ encoding_id = property(lambda self: self._FT_SfntName.encoding_id,
+ doc = '''The encoding ID for 'string'.''')
+
+ language_id = property(lambda self: self._FT_SfntName.language_id,
+ doc = '''The language ID for 'string'.''')
+
+ name_id = property(lambda self: self._FT_SfntName.name_id,
+ doc = '''An identifier for 'string'.''')
+
+ #string = property(lambda self: self._FT_SfntName.string)
+
+ string_len = property(lambda self: self._FT_SfntName.string_len,
+ doc = '''The length of 'string' in bytes.''')
+
+ def _get_string(self):
+ # #s = self._FT_SfntName
+ s = string_at(self._FT_SfntName.string, self._FT_SfntName.string_len)
+ return s
+ # #return s.decode('utf-16be', 'ignore')
+ # return s.decode('utf-8', 'ignore')
+ # #n = s.string_len
+ # #data = [s.string[i] for i in range(n)]
+ # #return data
+ string = property(_get_string,
+ doc = '''The 'name' string. Note that its format differs depending on
+ the (platform,encoding) pair. It can be a Pascal String, a
+ UTF-16 one, etc.
+
+ Generally speaking, the string is not zero-terminated. Please
+ refer to the TrueType specification for details.''')
+
+
+
+# -----------------------------------------------------------------------------
+class Stroker( object ):
+ '''
+ FT_Stroker wrapper
+
+ This component generates stroked outlines of a given vectorial glyph. It
+ also allows you to retrieve the 'outside' and/or the 'inside' borders of
+ the stroke.
+
+ This can be useful to generate 'bordered' glyph, i.e., glyphs displayed
+ with a coloured (and anti-aliased) border around their shape.
+ '''
+
+ def __init__( self ):
+ '''
+ Create a new Stroker object.
+ '''
+ library = get_handle( )
+ stroker = FT_Stroker( )
+ error = FT_Stroker_New( library, byref(stroker) )
+ if error: raise FT_Exception( error )
+ self._FT_Stroker = stroker
+
+
+ def __del__( self ):
+ '''
+ Destroy object.
+ '''
+ FT_Stroker_Done( self._FT_Stroker )
+
+
+ def set( self, radius, line_cap, line_join, miter_limit ):
+ '''
+ Reset a stroker object's attributes.
+
+ :param radius: The border radius.
+
+ :param line_cap: The line cap style.
+
+ :param line_join: The line join style.
+
+ :param miter_limit: The miter limit for the FT_STROKER_LINEJOIN_MITER
+ style, expressed as 16.16 fixed point value.
+
+ **Note**:
+
+ The radius is expressed in the same units as the outline coordinates.
+ '''
+ FT_Stroker_Set( self._FT_Stroker,
+ radius, line_cap, line_join, miter_limit )
+
+
+ def rewind( self ):
+ '''
+ Reset a stroker object without changing its attributes. You should call
+ this function before beginning a new series of calls to
+ FT_Stroker_BeginSubPath or FT_Stroker_EndSubPath.
+ '''
+ FT_Stroker_Rewind( self._FT_Stroker )
+
+
+ def parse_outline( self, outline, opened ):
+ '''
+ A convenience function used to parse a whole outline with the
+ stroker. The resulting outline(s) can be retrieved later by functions
+ like FT_Stroker_GetCounts and FT_Stroker_Export.
+
+ :param outline: The source outline.
+
+ :pram opened: A boolean. If 1, the outline is treated as an open path
+ instead of a closed one.
+
+ **Note**:
+
+ If 'opened' is 0 (the default), the outline is treated as a closed
+ path, and the stroker generates two distinct 'border' outlines.
+
+ If 'opened' is 1, the outline is processed as an open path, and the
+ stroker generates a single 'stroke' outline.
+
+ This function calls 'rewind' automatically.
+ '''
+ error = FT_Stroker_ParseOutline( self._FT_Stroker, outline, opened)
+ if error: raise FT_Exception( error )
+
+
+ def begin_subpath( self, to, _open ):
+ '''
+ Start a new sub-path in the stroker.
+
+ :param to A pointer to the start vector.
+
+ :param _open: A boolean. If 1, the sub-path is treated as an open one.
+
+ **Note**:
+
+ This function is useful when you need to stroke a path that is not
+ stored as an 'Outline' object.
+ '''
+ error = FT_Stroker_BeginSubPath( self._FT_Stroker, to, _open )
+ if error: raise FT_Exception( error )
+
+
+ def end_subpath( self ):
+ '''
+ Close the current sub-path in the stroker.
+
+ **Note**:
+
+ You should call this function after 'begin_subpath'. If the subpath
+ was not 'opened', this function 'draws' a single line segment to the
+ start position when needed.
+ '''
+ error = FT_Stroker_EndSubPath( self._FT_Stroker)
+ if error: raise FT_Exception( error )
+
+
+ def line_to( self, to ):
+ '''
+ 'Draw' a single line segment in the stroker's current sub-path, from
+ the last position.
+
+ :param to: A pointer to the destination point.
+
+ **Note**:
+
+ You should call this function between 'begin_subpath' and
+ 'end_subpath'.
+ '''
+ error = FT_Stroker_LineTo( self._FT_Stroker, to )
+ if error: raise FT_Exception( error )
+
+
+ def conic_to( self, control, to ):
+ '''
+ 'Draw' a single quadratic Bezier in the stroker's current sub-path,
+ from the last position.
+
+ :param control: A pointer to a Bezier control point.
+
+ :param to: A pointer to the destination point.
+
+ **Note**:
+
+ You should call this function between 'begin_subpath' and
+ 'end_subpath'.
+ '''
+ error = FT_Stroker_ConicTo( self._FT_Stroker, control, to )
+ if error: raise FT_Exception( error )
+
+
+ def cubic_to( self, control1, control2, to ):
+ '''
+ 'Draw' a single quadratic Bezier in the stroker's current sub-path,
+ from the last position.
+
+ :param control1: A pointer to the first Bezier control point.
+
+ :param control2: A pointer to second Bezier control point.
+
+ :param to: A pointer to the destination point.
+
+ **Note**:
+
+ You should call this function between 'begin_subpath' and
+ 'end_subpath'.
+ '''
+ error = FT_Stroker_CubicTo( self._FT_Stroker, control1, control2, to )
+ if error: raise FT_Exception( error )
+
+
+ def get_border_counts( self, border ):
+ '''
+ Call this function once you have finished parsing your paths with the
+ stroker. It returns the number of points and contours necessary to
+ export one of the 'border' or 'stroke' outlines generated by the
+ stroker.
+
+ :param border: The border index.
+
+ :return: number of points, number of contours
+ '''
+ anum_points = FT_UInt()
+ anum_contours = FT_UInt()
+ error = FT_Stroker_GetBorderCounts( self._FT_Stroker, border,
+ byref(anum_points), byref(anum_contours) )
+ if error: raise FT_Exception( error )
+ return anum_points.value, anum_contours.value
+
+
+ def export_border( self , border, outline ):
+ '''
+ Call this function after 'get_border_counts' to export the
+ corresponding border to your own 'Outline' structure.
+
+ Note that this function appends the border points and contours to your
+ outline, but does not try to resize its arrays.
+
+ :param border: The border index.
+
+ :param outline: The target outline.
+
+ **Note**:
+
+ Always call this function after get_border_counts to get sure that
+ there is enough room in your 'Outline' object to receive all new
+ data.
+
+ When an outline, or a sub-path, is 'closed', the stroker generates two
+ independent 'border' outlines, named 'left' and 'right'
+
+ When the outline, or a sub-path, is 'opened', the stroker merges the
+ 'border' outlines with caps. The 'left' border receives all points,
+ while the 'right' border becomes empty.
+
+ Use the function export instead if you want to retrieve all borders
+ at once.
+ '''
+ FT_Stroker_ExportBorder( self._FT_Stroker, border, outline._FT_Outline )
+
+
+ def get_counts( self ):
+ '''
+ Call this function once you have finished parsing your paths with the
+ stroker. It returns the number of points and contours necessary to
+ export all points/borders from the stroked outline/path.
+
+ :return: number of points, number of contours
+ '''
+
+ anum_points = FT_UInt()
+ anum_contours = FT_UInt()
+ error = FT_Stroker_GetCounts( self._FT_Stroker,
+ byref(anum_points), byref(anum_contours) )
+ if error: raise FT_Exception( error )
+ return anum_points.value, anum_contours.value
+
+
+ def export( self, outline ):
+ '''
+ Call this function after get_border_counts to export all borders to
+ your own 'Outline' structure.
+
+ Note that this function appends the border points and contours to your
+ outline, but does not try to resize its arrays.
+
+ :param outline: The target outline.
+ '''
+ FT_Stroker_Export( self._FT_Stroker, outline._FT_Outline )
diff --git a/third_party/freetype-py/freetype/ft_enums/__init__.py b/third_party/freetype-py/freetype/ft_enums/__init__.py
new file mode 100644
index 0000000..ac22a96
--- /dev/null
+++ b/third_party/freetype-py/freetype/ft_enums/__init__.py
@@ -0,0 +1,121 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# -----------------------------------------------------------------------------
+#
+# FreeType high-level python API - Copyright 2011 Nicolas P. Rougier
+# Distributed under the terms of the new BSD license.
+#
+# -----------------------------------------------------------------------------
+'''
+Freetype enum types
+-------------------
+
+FT_PIXEL_MODES: An enumeration type used to describe the format of pixels in a
+ given bitmap. Note that additional formats may be added in the
+ future.
+
+FT_GLYPH_BBOX_MODES: The mode how the values of FT_Glyph_Get_CBox are returned.
+
+FT_GLYPH_FORMATS: An enumeration type used to describe the format of a given
+ glyph image. Note that this version of FreeType only supports
+ two image formats, even though future font drivers will be
+ able to register their own format.
+
+FT_ENCODINGS: An enumeration used to specify character sets supported by
+ charmaps. Used in the FT_Select_Charmap API function.
+
+FT_RENDER_MODES: An enumeration type that lists the render modes supported by
+ FreeType 2. Each mode corresponds to a specific type of
+ scanline conversion performed on the outline.
+
+FT_LOAD_TARGETS: A list of values that are used to select a specific hinting
+ algorithm to use by the hinter. You should OR one of these
+ values to your 'load_flags' when calling FT_Load_Glyph.
+
+FT_LOAD_FLAGS: A list of bit-field constants used with FT_Load_Glyph to
+ indicate what kind of operations to perform during glyph
+ loading.
+
+FT_STYLE_FLAGS: A list of bit-flags used to indicate the style of a given
+ face. These are used in the 'style_flags' field of FT_FaceRec.
+
+FT_FSTYPES: A list of bit flags that inform client applications of embedding
+ and subsetting restrictions associated with a font.
+
+FT_FACE_FLAGS: A list of bit flags used in the 'face_flags' field of the
+ FT_FaceRec structure. They inform client applications of
+ properties of the corresponding face.
+
+FT_OUTLINE_FLAGS: A list of bit-field constants use for the flags in an
+ outline's 'flags' field.
+
+FT_OPEN_MODES: A list of bit-field constants used within the 'flags' field of
+ the FT_Open_Args structure.
+
+FT_KERNING_MODES: An enumeration used to specify which kerning values to return
+ in FT_Get_Kerning.
+
+FT_STROKER_LINEJOINS: These values determine how two joining lines are rendered
+ in a stroker.
+
+FT_STROKER_LINECAPS: These values determine how the end of opened sub-paths are
+ rendered in a stroke.
+
+FT_STROKER_BORDERS: These values are used to select a given stroke border in
+ FT_Stroker_GetBorderCounts and FT_Stroker_ExportBorder.
+
+FT_LCD_FILTERS: A list of values to identify various types of LCD filters.
+
+TT_PLATFORMS: A list of valid values for the 'platform_id' identifier code in
+ FT_CharMapRec and FT_SfntName structures.
+
+TT_APPLE_IDS: A list of valid values for the 'encoding_id' for
+ TT_PLATFORM_APPLE_UNICODE charmaps and name entries.
+
+TT_MAC_IDS: A list of valid values for the 'encoding_id' for
+ TT_PLATFORM_MACINTOSH charmaps and name entries.
+
+TT_MS_IDS: A list of valid values for the 'encoding_id' for
+ TT_PLATFORM_MICROSOFT charmaps and name entries.
+
+TT_ADOBE_IDS: A list of valid values for the 'encoding_id' for
+ TT_PLATFORM_ADOBE charmaps. This is a FreeType-specific
+ extension!
+
+TT_MAC_LANGIDS: Possible values of the language identifier field in the name
+ records of the TTF `name' table if the `platform' identifier
+ code is TT_PLATFORM_MACINTOSH.
+
+TT_MS_LANGIDS: Possible values of the language identifier field in the name
+ records of the TTF `name' table if the `platform' identifier
+ code is TT_PLATFORM_MICROSOFT.
+
+TT_NAME_IDS: Possible values of the `name' identifier field in the name
+ records of the TTF `name' table. These values are platform
+ independent.
+'''
+from freetype.ft_enums.ft_fstypes import *
+from freetype.ft_enums.ft_face_flags import *
+from freetype.ft_enums.ft_encodings import *
+from freetype.ft_enums.ft_glyph_bbox_modes import *
+from freetype.ft_enums.ft_glyph_formats import *
+from freetype.ft_enums.ft_kerning_modes import *
+from freetype.ft_enums.ft_lcd_filters import *
+from freetype.ft_enums.ft_load_flags import *
+from freetype.ft_enums.ft_load_targets import *
+from freetype.ft_enums.ft_open_modes import *
+from freetype.ft_enums.ft_outline_flags import *
+from freetype.ft_enums.ft_pixel_modes import *
+from freetype.ft_enums.ft_render_modes import *
+from freetype.ft_enums.ft_stroker_borders import *
+from freetype.ft_enums.ft_stroker_linecaps import *
+from freetype.ft_enums.ft_stroker_linejoins import *
+from freetype.ft_enums.ft_style_flags import *
+from freetype.ft_enums.tt_adobe_ids import *
+from freetype.ft_enums.tt_apple_ids import *
+from freetype.ft_enums.tt_mac_ids import *
+from freetype.ft_enums.tt_ms_ids import *
+from freetype.ft_enums.tt_ms_langids import *
+from freetype.ft_enums.tt_mac_langids import *
+from freetype.ft_enums.tt_name_ids import *
+from freetype.ft_enums.tt_platforms import *
diff --git a/third_party/freetype-py/freetype/ft_enums/ft_encodings.py b/third_party/freetype-py/freetype/ft_enums/ft_encodings.py
new file mode 100644
index 0000000..8c5db6b
--- /dev/null
+++ b/third_party/freetype-py/freetype/ft_enums/ft_encodings.py
@@ -0,0 +1,108 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# -----------------------------------------------------------------------------
+#
+# FreeType high-level python API - Copyright 2011-2012 Nicolas P. Rougier
+# Distributed under the terms of the new BSD license.
+#
+# -----------------------------------------------------------------------------
+"""
+An enumeration used to specify character sets supported by charmaps. Used in
+the FT_Select_Charmap API function.
+
+FT_ENCODING_NONE
+
+ The encoding value 0 is reserved.
+
+FT_ENCODING_UNICODE
+
+ Corresponds to the Unicode character set. This value covers all versions of
+ the Unicode repertoire, including ASCII and Latin-1. Most fonts include a
+ Unicode charmap, but not all of them.
+
+ For example, if you want to access Unicode value U+1F028 (and the font
+ contains it), use value 0x1F028 as the input value for FT_Get_Char_Index.
+
+FT_ENCODING_MS_SYMBOL
+
+ Corresponds to the Microsoft Symbol encoding, used to encode mathematical
+ symbols in the 32..255 character code range. For more information, see
+ 'http://www.ceviz.net/symbol.htm'.
+
+FT_ENCODING_SJIS
+
+ Corresponds to Japanese SJIS encoding. More info at at
+ 'http://langsupport.japanreference.com/encoding.shtml'. See note on
+ multi-byte encodings below.
+
+FT_ENCODING_GB2312
+
+ Corresponds to an encoding system for Simplified Chinese as used used in
+ mainland China.
+
+FT_ENCODING_BIG5
+
+ Corresponds to an encoding system for Traditional Chinese as used in Taiwan
+ and Hong Kong.
+
+FT_ENCODING_WANSUNG
+
+ Corresponds to the Korean encoding system known as Wansung. For more
+ information see 'http://www.microsoft.com/typography/unicode/949.txt'.
+
+FT_ENCODING_JOHAB
+
+ The Korean standard character set (KS C 5601-1992), which corresponds to MS
+ Windows code page 1361. This character set includes all possible Hangeul
+ character combinations.
+
+FT_ENCODING_ADOBE_LATIN_1
+
+ Corresponds to a Latin-1 encoding as defined in a Type 1 PostScript font. It
+ is limited to 256 character codes.
+
+FT_ENCODING_ADOBE_STANDARD
+
+ Corresponds to the Adobe Standard encoding, as found in Type 1, CFF, and
+ OpenType/CFF fonts. It is limited to 256 character codes.
+
+FT_ENCODING_ADOBE_EXPERT
+
+ Corresponds to the Adobe Expert encoding, as found in Type 1, CFF, and
+ OpenType/CFF fonts. It is limited to 256 character codes.
+
+FT_ENCODING_ADOBE_CUSTOM
+
+ Corresponds to a custom encoding, as found in Type 1, CFF, and OpenType/CFF
+ fonts. It is limited to 256 character codes.
+
+FT_ENCODING_APPLE_ROMAN
+
+ Corresponds to the 8-bit Apple roman encoding. Many TrueType and OpenType
+ fonts contain a charmap for this encoding, since older versions of Mac OS are
+ able to use it.
+
+FT_ENCODING_OLD_LATIN_2
+
+ This value is deprecated and was never used nor reported by FreeType. Don't
+ use or test for it.
+"""
+
+def _FT_ENC_TAG(a,b,c,d):
+ return ( ord(a) << 24 | ord(b) << 16 | ord(c) << 8 | ord(d) )
+
+FT_ENCODINGS = {'FT_ENCODING_NONE' : _FT_ENC_TAG('\0','\0','\0','\0'),
+ 'FT_ENCODING_MS_SYMBOL' : _FT_ENC_TAG( 's','y','m','b' ),
+ 'FT_ENCODING_UNICODE' : _FT_ENC_TAG( 'u','n','i','c' ),
+ 'FT_ENCODING_SJIS' : _FT_ENC_TAG( 's','j','i','s' ),
+ 'FT_ENCODING_GB2312' : _FT_ENC_TAG( 'g','b',' ',' ' ),
+ 'FT_ENCODING_BIG5' : _FT_ENC_TAG( 'b','i','g','5' ),
+ 'FT_ENCODING_WANSUNG' : _FT_ENC_TAG( 'w','a','n','s' ),
+ 'FT_ENCODING_JOHAB' : _FT_ENC_TAG( 'j','o','h','a' ),
+ 'FT_ENCODING_ADOBE_STANDARD' : _FT_ENC_TAG( 'A','D','O','B' ),
+ 'FT_ENCODING_ADOBE_EXPERT' : _FT_ENC_TAG( 'A','D','B','E' ),
+ 'FT_ENCODING_ADOBE_CUSTOM' : _FT_ENC_TAG( 'A','D','B','C' ),
+ 'FT_ENCODING_ADOBE_LATIN1' : _FT_ENC_TAG( 'l','a','t','1' ),
+ 'FT_ENCODING_OLD_LATIN2' : _FT_ENC_TAG( 'l','a','t','2' ),
+ 'FT_ENCODING_APPLE_ROMAN' : _FT_ENC_TAG( 'a','r','m','n' ) }
+globals().update(FT_ENCODINGS)
diff --git a/third_party/freetype-py/freetype/ft_enums/ft_face_flags.py b/third_party/freetype-py/freetype/ft_enums/ft_face_flags.py
new file mode 100644
index 0000000..4030437
--- /dev/null
+++ b/third_party/freetype-py/freetype/ft_enums/ft_face_flags.py
@@ -0,0 +1,134 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# -----------------------------------------------------------------------------
+#
+# FreeType high-level python API - Copyright 2011-2012 Nicolas P. Rougier
+# Distributed under the terms of the new BSD license.
+#
+# -----------------------------------------------------------------------------
+"""
+A list of bit flags used in the 'face_flags' field of the FT_FaceRec
+structure. They inform client applications of properties of the corresponding
+face.
+
+
+FT_FACE_FLAG_SCALABLE
+
+ Indicates that the face contains outline glyphs. This doesn't prevent bitmap
+ strikes, i.e., a face can have both this and and FT_FACE_FLAG_FIXED_SIZES
+ set.
+
+
+FT_FACE_FLAG_FIXED_SIZES
+
+ Indicates that the face contains bitmap strikes. See also the
+ 'num_fixed_sizes' and 'available_sizes' fields of FT_FaceRec.
+
+
+FT_FACE_FLAG_FIXED_WIDTH
+
+ Indicates that the face contains fixed-width characters (like Courier,
+ Lucido, MonoType, etc.).
+
+
+FT_FACE_FLAG_SFNT
+
+ Indicates that the face uses the 'sfnt' storage scheme. For now, this means
+ TrueType and OpenType.
+
+
+FT_FACE_FLAG_HORIZONTAL
+
+ Indicates that the face contains horizontal glyph metrics. This should be set
+ for all common formats.
+
+
+FT_FACE_FLAG_VERTICAL
+
+ Indicates that the face contains vertical glyph metrics. This is only
+ available in some formats, not all of them.
+
+
+FT_FACE_FLAG_KERNING
+
+ Indicates that the face contains kerning information. If set, the kerning
+ distance can be retrieved through the function FT_Get_Kerning. Otherwise the
+ function always return the vector (0,0). Note that FreeType doesn't handle
+ kerning data from the 'GPOS' table (as present in some OpenType fonts).
+
+
+FT_FACE_FLAG_MULTIPLE_MASTERS
+
+ Indicates that the font contains multiple masters and is capable of
+ interpolating between them. See the multiple-masters specific API for
+ details.
+
+
+FT_FACE_FLAG_GLYPH_NAMES
+
+ Indicates that the font contains glyph names that can be retrieved through
+ FT_Get_Glyph_Name. Note that some TrueType fonts contain broken glyph name
+ tables. Use the function FT_Has_PS_Glyph_Names when needed.
+
+
+FT_FACE_FLAG_EXTERNAL_STREAM
+
+ Used internally by FreeType to indicate that a face's stream was provided by
+ the client application and should not be destroyed when FT_Done_Face is
+ called. Don't read or test this flag.
+
+
+FT_FACE_FLAG_HINTER
+
+ Set if the font driver has a hinting machine of its own. For example, with
+ TrueType fonts, it makes sense to use data from the SFNT 'gasp' table only if
+ the native TrueType hinting engine (with the bytecode interpreter) is
+ available and active.
+
+
+FT_FACE_FLAG_CID_KEYED
+
+ Set if the font is CID-keyed. In that case, the font is not accessed by glyph
+ indices but by CID values. For subsetted CID-keyed fonts this has the
+ consequence that not all index values are a valid argument to
+ FT_Load_Glyph. Only the CID values for which corresponding glyphs in the
+ subsetted font exist make FT_Load_Glyph return successfully; in all other
+ cases you get an 'FT_Err_Invalid_Argument' error.
+
+ Note that CID-keyed fonts which are in an SFNT wrapper don't have this flag
+ set since the glyphs are accessed in the normal way (using contiguous
+ indices); the 'CID-ness' isn't visible to the application.
+
+
+FT_FACE_FLAG_TRICKY
+
+ Set if the font is 'tricky', this is, it always needs the font format's
+ native hinting engine to get a reasonable result. A typical example is the
+ Chinese font 'mingli.ttf' which uses TrueType bytecode instructions to move
+ and scale all of its subglyphs.
+
+ It is not possible to autohint such fonts using FT_LOAD_FORCE_AUTOHINT; it
+ will also ignore FT_LOAD_NO_HINTING. You have to set both FT_LOAD_NO_HINTING
+ and FT_LOAD_NO_AUTOHINT to really disable hinting; however, you probably
+ never want this except for demonstration purposes.
+
+ Currently, there are six TrueType fonts in the list of tricky fonts; they are
+ hard-coded in file 'ttobjs.c'.
+"""
+FT_FACE_FLAGS = { 'FT_FACE_FLAG_SCALABLE' : 1 << 0,
+ 'FT_FACE_FLAG_FIXED_SIZES' : 1 << 1,
+ 'FT_FACE_FLAG_FIXED_WIDTH' : 1 << 2,
+ 'FT_FACE_FLAG_SFNT' : 1 << 3,
+ 'FT_FACE_FLAG_HORIZONTAL' : 1 << 4,
+ 'FT_FACE_FLAG_VERTICAL' : 1 << 5,
+ 'FT_FACE_FLAG_KERNING' : 1 << 6,
+ 'FT_FACE_FLAG_FAST_GLYPHS' : 1 << 7,
+ 'FT_FACE_FLAG_MULTIPLE_MASTERS' : 1 << 8,
+ 'FT_FACE_FLAG_GLYPH_NAMES' : 1 << 9,
+ 'FT_FACE_FLAG_EXTERNAL_STREAM' : 1 << 10,
+ 'FT_FACE_FLAG_HINTER' : 1 << 11,
+ 'FT_FACE_FLAG_CID_KEYED' : 1 << 12,
+ 'FT_FACE_FLAG_TRICKY' : 1 << 13
+}
+globals().update(FT_FACE_FLAGS)
+
diff --git a/third_party/freetype-py/freetype/ft_enums/ft_fstypes.py b/third_party/freetype-py/freetype/ft_enums/ft_fstypes.py
new file mode 100644
index 0000000..4f4e2e0
--- /dev/null
+++ b/third_party/freetype-py/freetype/ft_enums/ft_fstypes.py
@@ -0,0 +1,65 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# -----------------------------------------------------------------------------
+#
+# FreeType high-level python API - Copyright 2011-2012 Nicolas P. Rougier
+# Distributed under the terms of the new BSD license.
+#
+# -----------------------------------------------------------------------------
+"""
+A list of bit flags that inform client applications of embedding and
+subsetting restrictions associated with a font.
+
+FT_FSTYPE_INSTALLABLE_EMBEDDING
+
+ Fonts with no fsType bit set may be embedded and permanently installed on
+ the remote system by an application.
+
+
+FT_FSTYPE_RESTRICTED_LICENSE_EMBEDDING
+
+ Fonts that have only this bit set must not be modified, embedded or exchanged
+ in any manner without first obtaining permission of the font software
+ copyright owner.
+
+
+FT_FSTYPE_PREVIEW_AND_PRINT_EMBEDDING
+
+ If this bit is set, the font may be embedded and temporarily loaded on the
+ remote system. Documents containing Preview & Print fonts must be opened
+ 'read-only'; no edits can be applied to the document.
+
+
+FT_FSTYPE_EDITABLE_EMBEDDING
+
+ If this bit is set, the font may be embedded but must only be installed
+ temporarily on other systems. In contrast to Preview & Print fonts,
+ documents containing editable fonts may be opened for reading, editing is
+ permitted, and changes may be saved.
+
+
+FT_FSTYPE_NO_SUBSETTING
+
+ If this bit is set, the font may not be subsetted prior to embedding.
+
+
+FT_FSTYPE_BITMAP_EMBEDDING_ONLY
+
+ If this bit is set, only bitmaps contained in the font may be embedded; no
+ outline data may be embedded. If there are no bitmaps available in the font,
+ then the font is unembeddable.
+"""
+
+FT_FSTYPES = {'FT_FSTYPE_INSTALLABLE_EMBEDDING' : 0x0000,
+ 'FT_FSTYPE_RESTRICTED_LICENSE_EMBEDDING' : 0x0002,
+ 'FT_FSTYPE_PREVIEW_AND_PRINT_EMBEDDING' : 0x0004,
+ 'FT_FSTYPE_EDITABLE_EMBEDDING' : 0x0008,
+ 'FT_FSTYPE_NO_SUBSETTING' : 0x0100,
+ 'FT_FSTYPE_BITMAP_EMBEDDING_ONLY' : 0x0200,}
+globals().update(FT_FSTYPES)
+ft_fstype_installable_embedding = FT_FSTYPE_INSTALLABLE_EMBEDDING
+ft_fstype_restricted_license_embedding = FT_FSTYPE_RESTRICTED_LICENSE_EMBEDDING
+ft_fstype_preview_and_print_embedding = FT_FSTYPE_PREVIEW_AND_PRINT_EMBEDDING
+ft_fstype_editable_embedding = FT_FSTYPE_EDITABLE_EMBEDDING
+ft_fstype_no_subsetting = FT_FSTYPE_NO_SUBSETTING
+ft_fstype_bitmap_embedding_only = FT_FSTYPE_BITMAP_EMBEDDING_ONLY
diff --git a/third_party/freetype-py/freetype/ft_enums/ft_glyph_bbox_modes.py b/third_party/freetype-py/freetype/ft_enums/ft_glyph_bbox_modes.py
new file mode 100644
index 0000000..2de7bb7
--- /dev/null
+++ b/third_party/freetype-py/freetype/ft_enums/ft_glyph_bbox_modes.py
@@ -0,0 +1,37 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# -----------------------------------------------------------------------------
+#
+# FreeType high-level python API - Copyright 2011-2012 Nicolas P. Rougier
+# Distributed under the terms of the new BSD license.
+#
+# -----------------------------------------------------------------------------
+"""
+The mode how the values of FT_Glyph_Get_CBox are returned.
+
+FT_GLYPH_BBOX_UNSCALED
+
+ Return unscaled font units.
+
+FT_GLYPH_BBOX_SUBPIXELS
+
+ Return unfitted 26.6 coordinates.
+
+FT_GLYPH_BBOX_GRIDFIT
+
+ Return grid-fitted 26.6 coordinates.
+
+FT_GLYPH_BBOX_TRUNCATE
+
+ Return coordinates in integer pixels.
+
+FT_GLYPH_BBOX_PIXELS
+
+ Return grid-fitted pixel coordinates.
+"""
+FT_GLYPH_BBOX_MODES = {'FT_GLYPH_BBOX_UNSCALED' : 0,
+ 'FT_GLYPH_BBOX_SUBPIXELS' : 0,
+ 'FT_GLYPH_BBOX_GRIDFIT' : 1,
+ 'FT_GLYPH_BBOX_TRUNCATE' : 2,
+ 'FT_GLYPH_BBOX_PIXELS' : 3}
+globals().update(FT_GLYPH_BBOX_MODES)
diff --git a/third_party/freetype-py/freetype/ft_enums/ft_glyph_formats.py b/third_party/freetype-py/freetype/ft_enums/ft_glyph_formats.py
new file mode 100644
index 0000000..8331719
--- /dev/null
+++ b/third_party/freetype-py/freetype/ft_enums/ft_glyph_formats.py
@@ -0,0 +1,58 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# -----------------------------------------------------------------------------
+#
+# FreeType high-level python API - Copyright 2011-2012 Nicolas P. Rougier
+# Distributed under the terms of the new BSD license.
+#
+# -----------------------------------------------------------------------------
+"""
+An enumeration type used to describe the format of a given glyph image. Note
+that this version of FreeType only supports two image formats, even though
+future font drivers will be able to register their own format.
+
+FT_GLYPH_FORMAT_NONE
+
+ The value 0 is reserved.
+
+FT_GLYPH_FORMAT_COMPOSITE
+
+ The glyph image is a composite of several other images. This format is only
+ used with FT_LOAD_NO_RECURSE, and is used to report compound glyphs (like
+ accented characters).
+
+FT_GLYPH_FORMAT_BITMAP
+
+ The glyph image is a bitmap, and can be described as an FT_Bitmap. You
+ generally need to access the 'bitmap' field of the FT_GlyphSlotRec structure
+ to read it.
+
+FT_GLYPH_FORMAT_OUTLINE
+
+ The glyph image is a vectorial outline made of line segments and Bezier arcs;
+ it can be described as an FT_Outline; you generally want to access the
+ 'outline' field of the FT_GlyphSlotRec structure to read it.
+
+FT_GLYPH_FORMAT_PLOTTER
+
+ The glyph image is a vectorial path with no inside and outside contours. Some
+ Type 1 fonts, like those in the Hershey family, contain glyphs in this
+ format. These are described as FT_Outline, but FreeType isn't currently
+ capable of rendering them correctly.
+"""
+
+def _FT_IMAGE_TAG(a,b,c,d):
+ return ( ord(a) << 24 | ord(b) << 16 | ord(c) << 8 | ord(d) )
+
+FT_GLYPH_FORMATS = {
+ 'FT_GLYPH_FORMAT_NONE' : _FT_IMAGE_TAG( '\0','\0','\0','\0' ),
+ 'FT_GLYPH_FORMAT_COMPOSITE' : _FT_IMAGE_TAG( 'c','o','m','p' ),
+ 'FT_GLYPH_FORMAT_BITMAP' : _FT_IMAGE_TAG( 'b','i','t','s' ),
+ 'FT_GLYPH_FORMAT_OUTLINE' : _FT_IMAGE_TAG( 'o','u','t','l' ),
+ 'FT_GLYPH_FORMAT_PLOTTER' : _FT_IMAGE_TAG( 'p','l','o','t' )}
+globals().update(FT_GLYPH_FORMATS)
+ft_glyph_format_none = FT_GLYPH_FORMAT_NONE
+ft_glyph_format_composite = FT_GLYPH_FORMAT_COMPOSITE
+ft_glyph_format_bitmap = FT_GLYPH_FORMAT_BITMAP
+ft_glyph_format_outline = FT_GLYPH_FORMAT_OUTLINE
+ft_glyph_format_plotter = FT_GLYPH_FORMAT_PLOTTER
diff --git a/third_party/freetype-py/freetype/ft_enums/ft_kerning_modes.py b/third_party/freetype-py/freetype/ft_enums/ft_kerning_modes.py
new file mode 100644
index 0000000..86341dc
--- /dev/null
+++ b/third_party/freetype-py/freetype/ft_enums/ft_kerning_modes.py
@@ -0,0 +1,31 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# -----------------------------------------------------------------------------
+#
+# FreeType high-level python API - Copyright 2011-2012 Nicolas P. Rougier
+# Distributed under the terms of the new BSD license.
+#
+# -----------------------------------------------------------------------------
+"""
+An enumeration used to specify which kerning values to return in
+FT_Get_Kerning.
+
+
+FT_KERNING_DEFAULT
+
+ Return scaled and grid-fitted kerning distances (value is 0).
+
+
+FT_KERNING_UNFITTED
+
+ Return scaled but un-grid-fitted kerning distances.
+
+
+FT_KERNING_UNSCALED
+
+ Return the kerning vector in original font units.
+"""
+FT_KERNING_MODES = { 'FT_KERNING_DEFAULT' : 0,
+ 'FT_KERNING_UNFITTED' : 1,
+ 'FT_KERNING_UNSCALED' : 2 }
+globals().update(FT_KERNING_MODES)
diff --git a/third_party/freetype-py/freetype/ft_enums/ft_lcd_filters.py b/third_party/freetype-py/freetype/ft_enums/ft_lcd_filters.py
new file mode 100644
index 0000000..355b190
--- /dev/null
+++ b/third_party/freetype-py/freetype/ft_enums/ft_lcd_filters.py
@@ -0,0 +1,51 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# -----------------------------------------------------------------------------
+#
+# FreeType high-level python API - Copyright 2011-2012 Nicolas P. Rougier
+# Distributed under the terms of the new BSD license.
+#
+# -----------------------------------------------------------------------------
+
+"""
+A list of values to identify various types of LCD filters.
+
+
+FT_LCD_FILTER_NONE
+
+ Do not perform filtering. When used with subpixel rendering, this results in
+ sometimes severe color fringes.
+
+
+FT_LCD_FILTER_DEFAULT
+
+ The default filter reduces color fringes considerably, at the cost of a
+ slight blurriness in the output.
+
+
+FT_LCD_FILTER_LIGHT
+
+ The light filter is a variant that produces less blurriness at the cost of
+ slightly more color fringes than the default one. It might be better,
+ depending on taste, your monitor, or your personal vision.
+
+
+FT_LCD_FILTER_LEGACY
+
+ This filter corresponds to the original libXft color filter. It provides high
+ contrast output but can exhibit really bad color fringes if glyphs are not
+ extremely well hinted to the pixel grid. In other words, it only works well
+ if the TrueType bytecode interpreter is enabled and high-quality hinted fonts
+ are used.
+
+ This filter is only provided for comparison purposes, and might be disabled
+ or stay unsupported in the future.
+"""
+
+FT_LCD_FILTERS = {'FT_LCD_FILTER_NONE' : 0,
+ 'FT_LCD_FILTER_DEFAULT' : 1,
+ 'FT_LCD_FILTER_LIGHT' : 2,
+ 'FT_LCD_FILTER_LEGACY' : 16}
+globals().update(FT_LCD_FILTERS)
+
+
diff --git a/third_party/freetype-py/freetype/ft_enums/ft_load_flags.py b/third_party/freetype-py/freetype/ft_enums/ft_load_flags.py
new file mode 100644
index 0000000..ad79b7b
--- /dev/null
+++ b/third_party/freetype-py/freetype/ft_enums/ft_load_flags.py
@@ -0,0 +1,154 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# -----------------------------------------------------------------------------
+#
+# FreeType high-level python API - Copyright 2011-2012 Nicolas P. Rougier
+# Distributed under the terms of the new BSD license.
+#
+# -----------------------------------------------------------------------------
+"""
+A list of bit-field constants used with FT_Load_Glyph to indicate what kind
+of operations to perform during glyph loading.
+
+
+FT_LOAD_DEFAULT
+
+ Corresponding to 0, this value is used as the default glyph load
+ operation. In this case, the following happens:
+
+ 1. FreeType looks for a bitmap for the glyph corresponding to the face's
+ current size. If one is found, the function returns. The bitmap data can
+ be accessed from the glyph slot (see note below).
+
+ 2. If no embedded bitmap is searched or found, FreeType looks for a scalable
+ outline. If one is found, it is loaded from the font file, scaled to
+ device pixels, then 'hinted' to the pixel grid in order to optimize
+ it. The outline data can be accessed from the glyph slot (see note below).
+
+ Note that by default, the glyph loader doesn't render outlines into
+ bitmaps. The following flags are used to modify this default behaviour to
+ more specific and useful cases.
+
+
+FT_LOAD_NO_SCALE
+
+ Don't scale the outline glyph loaded, but keep it in font units.
+
+ This flag implies FT_LOAD_NO_HINTING and FT_LOAD_NO_BITMAP, and unsets
+ FT_LOAD_RENDER.
+
+
+FT_LOAD_NO_HINTING
+
+ Disable hinting. This generally generates 'blurrier' bitmap glyph when the
+ glyph is rendered in any of the anti-aliased modes. See also the note below.
+
+ This flag is implied by FT_LOAD_NO_SCALE.
+
+
+FT_LOAD_RENDER
+
+ Call FT_Render_Glyph after the glyph is loaded. By default, the glyph is
+ rendered in FT_RENDER_MODE_NORMAL mode. This can be overridden by
+ FT_LOAD_TARGET_XXX or FT_LOAD_MONOCHROME.
+
+ This flag is unset by FT_LOAD_NO_SCALE.
+
+
+FT_LOAD_NO_BITMAP
+
+ Ignore bitmap strikes when loading. Bitmap-only fonts ignore this flag.
+
+ FT_LOAD_NO_SCALE always sets this flag.
+
+
+FT_LOAD_VERTICAL_LAYOUT
+
+ Load the glyph for vertical text layout. Don't use it as it is problematic
+ currently.
+
+
+FT_LOAD_FORCE_AUTOHINT
+
+ Indicates that the auto-hinter is preferred over the font's native
+ hinter. See also the note below.
+
+
+FT_LOAD_CROP_BITMAP
+
+ Indicates that the font driver should crop the loaded bitmap glyph (i.e.,
+ remove all space around its black bits). Not all drivers implement this.
+
+
+FT_LOAD_PEDANTIC
+
+ Indicates that the font driver should perform pedantic verifications during
+ glyph loading. This is mostly used to detect broken glyphs in fonts. By
+ default, FreeType tries to handle broken fonts also.
+
+
+FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH
+
+ Indicates that the font driver should ignore the global advance width defined
+ in the font. By default, that value is used as the advance width for all
+ glyphs when the face has FT_FACE_FLAG_FIXED_WIDTH set.
+
+ This flag exists for historical reasons (to support buggy CJK fonts).
+
+
+FT_LOAD_NO_RECURSE
+
+ This flag is only used internally. It merely indicates that the font driver
+ should not load composite glyphs recursively. Instead, it should set the
+ 'num_subglyph' and 'subglyphs' values of the glyph slot accordingly, and set
+ 'glyph->format' to FT_GLYPH_FORMAT_COMPOSITE.
+
+ The description of sub-glyphs is not available to client applications for now.
+
+ This flag implies FT_LOAD_NO_SCALE and FT_LOAD_IGNORE_TRANSFORM.
+
+
+FT_LOAD_IGNORE_TRANSFORM
+
+ Indicates that the transform matrix set by FT_Set_Transform should be ignored.
+
+
+FT_LOAD_MONOCHROME
+
+ This flag is used with FT_LOAD_RENDER to indicate that you want to render an
+ outline glyph to a 1-bit monochrome bitmap glyph, with 8 pixels packed into
+ each byte of the bitmap data.
+
+ Note that this has no effect on the hinting algorithm used. You should rather
+ use FT_LOAD_TARGET_MONO so that the monochrome-optimized hinting algorithm is
+ used.
+
+
+FT_LOAD_LINEAR_DESIGN
+
+ Indicates that the 'linearHoriAdvance' and 'linearVertAdvance' fields of
+ FT_GlyphSlotRec should be kept in font units. See FT_GlyphSlotRec for
+ details.
+
+
+FT_LOAD_NO_AUTOHINT
+
+ Disable auto-hinter. See also the note below.
+"""
+
+FT_LOAD_FLAGS = { 'FT_LOAD_DEFAULT' : 0x0,
+ 'FT_LOAD_NO_SCALE' : 0x1,
+ 'FT_LOAD_NO_HINTING' : 0x2,
+ 'FT_LOAD_RENDER' : 0x4,
+ 'FT_LOAD_NO_BITMAP' : 0x8,
+ 'FT_LOAD_VERTICAL_LAYOUT' : 0x10,
+ 'FT_LOAD_FORCE_AUTOHINT' : 0x20,
+ 'FT_LOAD_CROP_BITMAP' : 0x40,
+ 'FT_LOAD_PEDANTIC' : 0x80,
+ 'FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH' : 0x200,
+ 'FT_LOAD_NO_RECURSE' : 0x400,
+ 'FT_LOAD_IGNORE_TRANSFORM' : 0x800,
+ 'FT_LOAD_MONOCHROME' : 0x1000,
+ 'FT_LOAD_LINEAR_DESIGN' : 0x2000,
+ 'FT_LOAD_NO_AUTOHINT' : 0x8000 }
+globals().update(FT_LOAD_FLAGS)
diff --git a/third_party/freetype-py/freetype/ft_enums/ft_load_targets.py b/third_party/freetype-py/freetype/ft_enums/ft_load_targets.py
new file mode 100644
index 0000000..17e4949
--- /dev/null
+++ b/third_party/freetype-py/freetype/ft_enums/ft_load_targets.py
@@ -0,0 +1,70 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# -----------------------------------------------------------------------------
+#
+# FreeType high-level python API - Copyright 2011-2012 Nicolas P. Rougier
+# Distributed under the terms of the new BSD license.
+#
+# -----------------------------------------------------------------------------
+"""
+A list of values that are used to select a specific hinting algorithm to use
+by the hinter. You should OR one of these values to your 'load_flags' when
+calling FT_Load_Glyph.
+
+Note that font's native hinters may ignore the hinting algorithm you have
+specified (e.g., the TrueType bytecode interpreter). You can set
+FT_LOAD_FORCE_AUTOHINT to ensure that the auto-hinter is used.
+
+Also note that FT_LOAD_TARGET_LIGHT is an exception, in that it always
+implies FT_LOAD_FORCE_AUTOHINT.
+
+
+FT_LOAD_TARGET_NORMAL
+
+ This corresponds to the default hinting algorithm, optimized for standard
+ gray-level rendering. For monochrome output, use FT_LOAD_TARGET_MONO instead.
+
+
+FT_LOAD_TARGET_LIGHT
+
+ A lighter hinting algorithm for non-monochrome modes. Many generated glyphs
+ are more fuzzy but better resemble its original shape. A bit like rendering
+ on Mac OS X.
+
+ As a special exception, this target implies FT_LOAD_FORCE_AUTOHINT.
+
+
+FT_LOAD_TARGET_MONO
+
+ Strong hinting algorithm that should only be used for monochrome output. The
+ result is probably unpleasant if the glyph is rendered in non-monochrome
+ modes.
+
+
+FT_LOAD_TARGET_LCD
+
+ A variant of FT_LOAD_TARGET_NORMAL optimized for horizontally decimated LCD
+ displays.
+
+
+FT_LOAD_TARGET_LCD_V
+
+ A variant of FT_LOAD_TARGET_NORMAL optimized for vertically decimated LCD
+ displays.
+"""
+
+from freetype.ft_enums.ft_render_modes import *
+
+
+def _FT_LOAD_TARGET_(x):
+ return (x & 15) << 16
+FT_LOAD_TARGETS = {
+ 'FT_LOAD_TARGET_NORMAL' : _FT_LOAD_TARGET_(FT_RENDER_MODE_NORMAL),
+ 'FT_LOAD_TARGET_LIGHT' : _FT_LOAD_TARGET_(FT_RENDER_MODE_LIGHT),
+ 'FT_LOAD_TARGET_MONO' : _FT_LOAD_TARGET_(FT_RENDER_MODE_MONO),
+ 'FT_LOAD_TARGET_LCD' : _FT_LOAD_TARGET_(FT_RENDER_MODE_LCD),
+ 'FT_LOAD_TARGET_LCD_V' : _FT_LOAD_TARGET_(FT_RENDER_MODE_LCD_V) }
+globals().update(FT_LOAD_TARGETS)
+#def FT_LOAD_TARGET_MODE(x):
+# return (x >> 16) & 15
+
diff --git a/third_party/freetype-py/freetype/ft_enums/ft_open_modes.py b/third_party/freetype-py/freetype/ft_enums/ft_open_modes.py
new file mode 100644
index 0000000..b1149a5
--- /dev/null
+++ b/third_party/freetype-py/freetype/ft_enums/ft_open_modes.py
@@ -0,0 +1,45 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# -----------------------------------------------------------------------------
+#
+# FreeType high-level python API - Copyright 2011-2012 Nicolas P. Rougier
+# Distributed under the terms of the new BSD license.
+#
+# -----------------------------------------------------------------------------
+"""
+A list of bit-field constants used within the 'flags' field of the
+FT_Open_Args structure.
+
+
+FT_OPEN_MEMORY
+
+ This is a memory-based stream.
+
+
+FT_OPEN_STREAM
+
+ Copy the stream from the 'stream' field.
+
+
+FT_OPEN_PATHNAME
+
+ Create a new input stream from a C path name.
+
+
+FT_OPEN_DRIVER
+
+ Use the 'driver' field.
+
+
+FT_OPEN_PARAMS
+
+ Use the 'num_params' and 'params' fields.
+"""
+FT_OPEN_MODES = {'FT_OPEN_MEMORY': 0x1,
+ 'FT_OPEN_STREAM': 0x2,
+ 'FT_OPEN_PATHNAME': 0x4,
+ 'FT_OPEN_DRIVER': 0x8,
+ 'FT_OPEN_PARAMS': 0x10 }
+globals().update(FT_OPEN_MODES)
+
+
diff --git a/third_party/freetype-py/freetype/ft_enums/ft_outline_flags.py b/third_party/freetype-py/freetype/ft_enums/ft_outline_flags.py
new file mode 100644
index 0000000..644c225
--- /dev/null
+++ b/third_party/freetype-py/freetype/ft_enums/ft_outline_flags.py
@@ -0,0 +1,87 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# -----------------------------------------------------------------------------
+#
+# FreeType high-level python API - Copyright 2011 Nicolas P. Rougier
+# Distributed under the terms of the new BSD license.
+#
+# -----------------------------------------------------------------------------
+"""
+A list of bit-field constants use for the flags in an outline's 'flags'
+field.
+
+
+FT_OUTLINE_NONE
+
+ Value 0 is reserved.
+
+
+FT_OUTLINE_OWNER
+
+ If set, this flag indicates that the outline's field arrays (i.e., 'points',
+ 'flags', and 'contours') are 'owned' by the outline object, and should thus
+ be freed when it is destroyed.
+
+
+FT_OUTLINE_EVEN_ODD_FILL
+
+ By default, outlines are filled using the non-zero winding rule. If set to 1,
+ the outline will be filled using the even-odd fill rule (only works with the
+ smooth rasterizer).
+
+
+FT_OUTLINE_REVERSE_FILL
+
+ By default, outside contours of an outline are oriented in clock-wise
+ direction, as defined in the TrueType specification. This flag is set if the
+ outline uses the opposite direction (typically for Type 1 fonts). This flag
+ is ignored by the scan converter.
+
+
+FT_OUTLINE_IGNORE_DROPOUTS
+
+ By default, the scan converter will try to detect drop-outs in an outline and
+ correct the glyph bitmap to ensure consistent shape continuity. If set, this
+ flag hints the scan-line converter to ignore such cases. See below for more
+ information.
+
+
+FT_OUTLINE_SMART_DROPOUTS
+
+ Select smart dropout control. If unset, use simple dropout control. Ignored
+ if FT_OUTLINE_IGNORE_DROPOUTS is set. See below for more information.
+
+
+FT_OUTLINE_INCLUDE_STUBS
+
+ If set, turn pixels on for 'stubs', otherwise exclude them. Ignored if
+ FT_OUTLINE_IGNORE_DROPOUTS is set. See below for more information.
+
+
+FT_OUTLINE_HIGH_PRECISION
+
+ This flag indicates that the scan-line converter should try to convert this
+ outline to bitmaps with the highest possible quality. It is typically set for
+ small character sizes. Note that this is only a hint that might be completely
+ ignored by a given scan-converter.
+
+
+FT_OUTLINE_SINGLE_PASS
+
+ This flag is set to force a given scan-converter to only use a single pass
+ over the outline to render a bitmap glyph image. Normally, it is set for very
+ large character sizes. It is only a hint that might be completely ignored by
+ a given scan-converter.
+"""
+FT_OUTLINE_FLAGS = { 'FT_OUTLINE_NONE' : 0x0,
+ 'FT_OUTLINE_OWNER' : 0x1,
+ 'FT_OUTLINE_EVEN_ODD_FILL' : 0x2,
+ 'FT_OUTLINE_REVERSE_FILL' : 0x4,
+ 'FT_OUTLINE_IGNORE_DROPOUTS' : 0x8,
+ 'FT_OUTLINE_SMART_DROPOUTS' : 0x10,
+ 'FT_OUTLINE_INCLUDE_STUBS' : 0x20,
+ 'FT_OUTLINE_HIGH_PRECISION' : 0x100,
+ 'FT_OUTLINE_SINGLE_PASS' : 0x200 }
+globals().update(FT_OUTLINE_FLAGS)
+
+
diff --git a/third_party/freetype-py/freetype/ft_enums/ft_pixel_modes.py b/third_party/freetype-py/freetype/ft_enums/ft_pixel_modes.py
new file mode 100644
index 0000000..2e11ed9
--- /dev/null
+++ b/third_party/freetype-py/freetype/ft_enums/ft_pixel_modes.py
@@ -0,0 +1,77 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# -----------------------------------------------------------------------------
+#
+# FreeType high-level python API - Copyright 2011-2012 Nicolas P. Rougier
+# Distributed under the terms of the new BSD license.
+#
+# -----------------------------------------------------------------------------
+"""
+An enumeration type that lists the render modes supported by FreeType 2. Each
+mode corresponds to a specific type of scanline conversion performed on the
+outline.
+
+
+FT_PIXEL_MODE_NONE
+
+ Value 0 is reserved.
+
+
+FT_PIXEL_MODE_MONO
+
+ A monochrome bitmap, using 1 bit per pixel. Note that pixels are stored in
+ most-significant order (MSB), which means that the left-most pixel in a byte
+ has value 128.
+
+
+FT_PIXEL_MODE_GRAY
+
+ An 8-bit bitmap, generally used to represent anti-aliased glyph images. Each
+ pixel is stored in one byte. Note that the number of 'gray' levels is stored
+ in the 'num_grays' field of the FT_Bitmap structure (it generally is 256).
+
+
+FT_PIXEL_MODE_GRAY2
+
+ A 2-bit per pixel bitmap, used to represent embedded anti-aliased bitmaps in
+ font files according to the OpenType specification. We haven't found a single
+ font using this format, however.
+
+
+FT_PIXEL_MODE_GRAY4
+
+ A 4-bit per pixel bitmap, representing embedded anti-aliased bitmaps in font
+ files according to the OpenType specification. We haven't found a single font
+ using this format, however.
+
+
+FT_PIXEL_MODE_LCD
+
+ An 8-bit bitmap, representing RGB or BGR decimated glyph images used for
+ display on LCD displays; the bitmap is three times wider than the original
+ glyph image. See also FT_RENDER_MODE_LCD.
+
+
+FT_PIXEL_MODE_LCD_V
+
+ An 8-bit bitmap, representing RGB or BGR decimated glyph images used for
+ display on rotated LCD displays; the bitmap is three times taller than the
+ original glyph image. See also FT_RENDER_MODE_LCD_V.
+
+"""
+
+FT_PIXEL_MODES = {'FT_PIXEL_MODE_NONE' : 0,
+ 'FT_PIXEL_MODE_MONO' : 1,
+ 'FT_PIXEL_MODE_GRAY' : 2,
+ 'FT_PIXEL_MODE_GRAY2': 3,
+ 'FT_PIXEL_MODE_GRAY4': 4,
+ 'FT_PIXEL_MODE_LCD' : 5,
+ 'FT_PIXEL_MODE_LCD_V': 6,
+ 'FT_PIXEL_MODE_MAX' : 7}
+globals().update(FT_PIXEL_MODES)
+ft_pixel_mode_none = FT_PIXEL_MODE_NONE
+ft_pixel_mode_mono = FT_PIXEL_MODE_MONO
+ft_pixel_mode_grays = FT_PIXEL_MODE_GRAY
+ft_pixel_mode_pal2 = FT_PIXEL_MODE_GRAY2
+ft_pixel_mode_pal4 = FT_PIXEL_MODE_GRAY4
+
diff --git a/third_party/freetype-py/freetype/ft_enums/ft_render_modes.py b/third_party/freetype-py/freetype/ft_enums/ft_render_modes.py
new file mode 100644
index 0000000..dcda06f
--- /dev/null
+++ b/third_party/freetype-py/freetype/ft_enums/ft_render_modes.py
@@ -0,0 +1,57 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# -----------------------------------------------------------------------------
+#
+# FreeType high-level python API - Copyright 2011-2012 Nicolas P. Rougier
+# Distributed under the terms of the new BSD license.
+#
+# -----------------------------------------------------------------------------
+"""
+An enumeration type that lists the render modes supported by FreeType 2. Each
+mode corresponds to a specific type of scanline conversion performed on the
+outline.
+
+For bitmap fonts and embedded bitmaps the 'bitmap->pixel_mode' field in the
+FT_GlyphSlotRec structure gives the format of the returned bitmap.
+
+All modes except FT_RENDER_MODE_MONO use 256 levels of opacity.
+
+
+FT_RENDER_MODE_NORMAL
+
+ This is the default render mode; it corresponds to 8-bit anti-aliased
+ bitmaps.
+
+
+FT_RENDER_MODE_LIGHT
+
+ This is equivalent to FT_RENDER_MODE_NORMAL. It is only defined as a separate
+ value because render modes are also used indirectly to define hinting
+ algorithm selectors. See FT_LOAD_TARGET_XXX for details.
+
+
+FT_RENDER_MODE_MONO
+
+ This mode corresponds to 1-bit bitmaps (with 2 levels of opacity).
+
+
+FT_RENDER_MODE_LCD
+
+ This mode corresponds to horizontal RGB and BGR sub-pixel displays like LCD
+ screens. It produces 8-bit bitmaps that are 3 times the width of the original
+ glyph outline in pixels, and which use the FT_PIXEL_MODE_LCD mode.
+
+
+FT_RENDER_MODE_LCD_V
+
+ This mode corresponds to vertical RGB and BGR sub-pixel displays (like PDA
+ screens, rotated LCD displays, etc.). It produces 8-bit bitmaps that are 3
+ times the height of the original glyph outline in pixels and use the
+ FT_PIXEL_MODE_LCD_V mode.
+"""
+FT_RENDER_MODES = { 'FT_RENDER_MODE_NORMAL' : 0,
+ 'FT_RENDER_MODE_LIGHT' : 1,
+ 'FT_RENDER_MODE_MONO' : 2,
+ 'FT_RENDER_MODE_LCD' : 3,
+ 'FT_RENDER_MODE_LCD_V' : 4 }
+globals().update(FT_RENDER_MODES)
diff --git a/third_party/freetype-py/freetype/ft_enums/ft_stroker_borders.py b/third_party/freetype-py/freetype/ft_enums/ft_stroker_borders.py
new file mode 100644
index 0000000..0c62cd4
--- /dev/null
+++ b/third_party/freetype-py/freetype/ft_enums/ft_stroker_borders.py
@@ -0,0 +1,38 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# -----------------------------------------------------------------------------
+#
+# FreeType high-level python API - Copyright 2011-2012 Nicolas P. Rougier
+# Distributed under the terms of the new BSD license.
+#
+# -----------------------------------------------------------------------------
+"""
+These values are used to select a given stroke border in
+FT_Stroker_GetBorderCounts and FT_Stroker_ExportBorder.
+
+
+FT_STROKER_BORDER_LEFT
+
+ Select the left border, relative to the drawing direction.
+
+
+FT_STROKER_BORDER_RIGHT
+
+ Select the right border, relative to the drawing direction.
+
+
+Note
+
+ Applications are generally interested in the 'inside' and 'outside'
+ borders. However, there is no direct mapping between these and the 'left' and
+ 'right' ones, since this really depends on the glyph's drawing orientation,
+ which varies between font formats.
+
+ You can however use FT_Outline_GetInsideBorder and
+ FT_Outline_GetOutsideBorder to get these.
+"""
+FT_STROKER_BORDERS = { 'FT_STROKER_BORDER_LEFT' : 0,
+ 'FT_STROKER_BORDER_RIGHT' : 1}
+globals().update(FT_STROKER_BORDERS)
+
+
diff --git a/third_party/freetype-py/freetype/ft_enums/ft_stroker_linecaps.py b/third_party/freetype-py/freetype/ft_enums/ft_stroker_linecaps.py
new file mode 100644
index 0000000..19ebf1d
--- /dev/null
+++ b/third_party/freetype-py/freetype/ft_enums/ft_stroker_linecaps.py
@@ -0,0 +1,34 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# -----------------------------------------------------------------------------
+#
+# FreeType high-level python API - Copyright 2011-2012 Nicolas P. Rougier
+# Distributed under the terms of the new BSD license.
+#
+# -----------------------------------------------------------------------------
+"""
+These values determine how the end of opened sub-paths are rendered in a
+stroke.
+
+
+FT_STROKER_LINECAP_BUTT
+
+ The end of lines is rendered as a full stop on the last point itself.
+
+
+FT_STROKER_LINECAP_ROUND
+
+ The end of lines is rendered as a half-circle around the last point.
+
+
+FT_STROKER_LINECAP_SQUARE
+
+ The end of lines is rendered as a square around the last point.
+"""
+
+FT_STROKER_LINECAPS = { 'FT_STROKER_LINECAP_BUTT' : 0,
+ 'FT_STROKER_LINECAP_ROUND' : 1,
+ 'FT_STROKER_LINECAP_SQUARE' : 2}
+globals().update(FT_STROKER_LINECAPS)
+
+
diff --git a/third_party/freetype-py/freetype/ft_enums/ft_stroker_linejoins.py b/third_party/freetype-py/freetype/ft_enums/ft_stroker_linejoins.py
new file mode 100644
index 0000000..f88191b
--- /dev/null
+++ b/third_party/freetype-py/freetype/ft_enums/ft_stroker_linejoins.py
@@ -0,0 +1,36 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# -----------------------------------------------------------------------------
+#
+# FreeType high-level python API - Copyright 2011-2012 Nicolas P. Rougier
+# Distributed under the terms of the new BSD license.
+#
+# -----------------------------------------------------------------------------
+"""
+These values determine how two joining lines are rendered in a stroker.
+
+
+FT_STROKER_LINEJOIN_ROUND
+
+ Used to render rounded line joins. Circular arcs are used to join two lines
+ smoothly.
+
+
+FT_STROKER_LINEJOIN_BEVEL
+
+ Used to render beveled line joins; i.e., the two joining lines are extended
+ until they intersect.
+
+
+FT_STROKER_LINEJOIN_MITER
+
+ Same as beveled rendering, except that an additional line break is added if
+ the angle between the two joining lines is too closed (this is useful to
+ avoid unpleasant spikes in beveled rendering).
+"""
+FT_STROKER_LINEJOINS = { 'FT_STROKER_LINEJOIN_ROUND' : 0,
+ 'FT_STROKER_LINEJOIN_BEVEL' : 1,
+ 'FT_STROKER_LINEJOIN_MITER' : 2}
+globals().update(FT_STROKER_LINEJOINS)
+
+
diff --git a/third_party/freetype-py/freetype/ft_enums/ft_style_flags.py b/third_party/freetype-py/freetype/ft_enums/ft_style_flags.py
new file mode 100644
index 0000000..e0032c9
--- /dev/null
+++ b/third_party/freetype-py/freetype/ft_enums/ft_style_flags.py
@@ -0,0 +1,28 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# -----------------------------------------------------------------------------
+#
+# FreeType high-level python API - Copyright 2011-2012 Nicolas P. Rougier
+# Distributed under the terms of the new BSD license.
+#
+# -----------------------------------------------------------------------------
+"""
+A list of bit-flags used to indicate the style of a given face. These are
+used in the 'style_flags' field of FT_FaceRec.
+
+
+FT_STYLE_FLAG_ITALIC
+
+ Indicates that a given face style is italic or oblique.
+
+
+FT_STYLE_FLAG_BOLD
+
+ Indicates that a given face is bold.
+"""
+FT_STYLE_FLAGS = {'FT_STYLE_FLAG_ITALIC' : 1,
+ 'FT_STYLE_FLAG_BOLD' : 2 }
+globals().update(FT_STYLE_FLAGS)
+
+
+
diff --git a/third_party/freetype-py/freetype/ft_enums/tt_adobe_ids.py b/third_party/freetype-py/freetype/ft_enums/tt_adobe_ids.py
new file mode 100644
index 0000000..40e243c
--- /dev/null
+++ b/third_party/freetype-py/freetype/ft_enums/tt_adobe_ids.py
@@ -0,0 +1,38 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# -----------------------------------------------------------------------------
+#
+# FreeType high-level python API - Copyright 2011-2012 Nicolas P. Rougier
+# Distributed under the terms of the new BSD license.
+#
+# -----------------------------------------------------------------------------
+"""
+A list of valid values for the 'encoding_id' for TT_PLATFORM_ADOBE
+charmaps. This is a FreeType-specific extension!
+
+TT_ADOBE_ID_STANDARD
+
+ Adobe standard encoding.
+
+
+TT_ADOBE_ID_EXPERT
+
+ Adobe expert encoding.
+
+
+TT_ADOBE_ID_CUSTOM
+
+ Adobe custom encoding.
+
+
+TT_ADOBE_ID_LATIN_1
+
+ Adobe Latin 1 encoding.
+"""
+
+TT_ADOBE_IDS = {
+ 'TT_ADOBE_ID_STANDARD' : 0,
+ 'TT_ADOBE_ID_EXPERT' : 1,
+ 'TT_ADOBE_ID_CUSTOM' : 2,
+ 'TT_ADOBE_ID_LATIN_1' : 3 }
+globals().update(TT_ADOBE_IDS)
diff --git a/third_party/freetype-py/freetype/ft_enums/tt_apple_ids.py b/third_party/freetype-py/freetype/ft_enums/tt_apple_ids.py
new file mode 100644
index 0000000..3d39fbd
--- /dev/null
+++ b/third_party/freetype-py/freetype/ft_enums/tt_apple_ids.py
@@ -0,0 +1,53 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# -----------------------------------------------------------------------------
+#
+# FreeType high-level python API - Copyright 2011-2012 Nicolas P. Rougier
+# Distributed under the terms of the new BSD license.
+#
+# -----------------------------------------------------------------------------
+"""
+A list of valid values for the 'encoding_id' for TT_PLATFORM_APPLE_UNICODE
+charmaps and name entries.
+
+
+TT_APPLE_ID_DEFAULT
+
+ Unicode version 1.0.
+
+
+TT_APPLE_ID_UNICODE_1_1
+
+ Unicode 1.1; specifies Hangul characters starting at U+34xx.
+
+
+TT_APPLE_ID_ISO_10646
+
+ Deprecated (identical to preceding).
+
+
+TT_APPLE_ID_UNICODE_2_0
+
+ Unicode 2.0 and beyond (UTF-16 BMP only).
+
+
+TT_APPLE_ID_UNICODE_32
+
+ Unicode 3.1 and beyond, using UTF-32.
+
+
+TT_APPLE_ID_VARIANT_SELECTOR
+
+ From Adobe, not Apple. Not a normal cmap. Specifies variations on a real
+ cmap.
+"""
+TT_APPLE_IDS = {
+ 'TT_APPLE_ID_DEFAULT' : 0,
+ 'TT_APPLE_ID_UNICODE_1_1' : 1,
+ 'TT_APPLE_ID_ISO_10646' : 2,
+ 'TT_APPLE_ID_UNICODE_2_0' : 3,
+ 'TT_APPLE_ID_UNICODE_32' : 4,
+ 'TT_APPLE_ID_VARIANT_SELECTOR' : 5 }
+globals().update(TT_APPLE_IDS)
+
+
diff --git a/third_party/freetype-py/freetype/ft_enums/tt_mac_ids.py b/third_party/freetype-py/freetype/ft_enums/tt_mac_ids.py
new file mode 100644
index 0000000..e455772
--- /dev/null
+++ b/third_party/freetype-py/freetype/ft_enums/tt_mac_ids.py
@@ -0,0 +1,117 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# -----------------------------------------------------------------------------
+#
+# FreeType high-level python API - Copyright 2011-2012 Nicolas P. Rougier
+# Distributed under the terms of the new BSD license.
+#
+# -----------------------------------------------------------------------------
+"""
+A list of valid values for the 'encoding_id' for TT_PLATFORM_MACINTOSH
+charmaps and name entries.
+
+TT_MAC_ID_ROMAN
+
+TT_MAC_ID_TELUGU
+
+TT_MAC_ID_GURMUKHI
+
+TT_MAC_ID_TIBETAN
+
+TT_MAC_ID_SIMPLIFIED_CHINESE
+
+TT_MAC_ID_SINDHI
+
+TT_MAC_ID_SINHALESE
+
+TT_MAC_ID_RUSSIAN
+
+TT_MAC_ID_KANNADA
+
+TT_MAC_ID_VIETNAMESE
+
+TT_MAC_ID_MONGOLIAN
+
+TT_MAC_ID_DEVANAGARI
+
+TT_MAC_ID_HEBREW
+
+TT_MAC_ID_TAMIL
+
+TT_MAC_ID_THAI
+
+TT_MAC_ID_BURMESE
+
+TT_MAC_ID_MALDIVIAN
+
+TT_MAC_ID_TRADITIONAL_CHINESE
+
+TT_MAC_ID_JAPANESE
+
+TT_MAC_ID_GREEK
+
+TT_MAC_ID_LAOTIAN
+
+TT_MAC_ID_KHMER
+
+TT_MAC_ID_UNINTERP
+
+TT_MAC_ID_ORIYA
+
+TT_MAC_ID_RSYMBOL
+
+TT_MAC_ID_MALAYALAM
+
+TT_MAC_ID_GEEZ
+
+TT_MAC_ID_KOREAN
+
+TT_MAC_ID_GUJARATI
+
+TT_MAC_ID_BENGALI
+
+TT_MAC_ID_ARABIC
+
+TT_MAC_ID_GEORGIAN
+
+TT_MAC_ID_ARMENIAN
+
+TT_MAC_ID_SLAVIC
+"""
+
+TT_MAC_IDS = {
+ 'TT_MAC_ID_ROMAN' : 0,
+ 'TT_MAC_ID_JAPANESE' : 1,
+ 'TT_MAC_ID_TRADITIONAL_CHINESE' : 2,
+ 'TT_MAC_ID_KOREAN' : 3,
+ 'TT_MAC_ID_ARABIC' : 4,
+ 'TT_MAC_ID_HEBREW' : 5,
+ 'TT_MAC_ID_GREEK' : 6,
+ 'TT_MAC_ID_RUSSIAN' : 7,
+ 'TT_MAC_ID_RSYMBOL' : 8,
+ 'TT_MAC_ID_DEVANAGARI' : 9,
+ 'TT_MAC_ID_GURMUKHI' : 10,
+ 'TT_MAC_ID_GUJARATI' : 11,
+ 'TT_MAC_ID_ORIYA' : 12,
+ 'TT_MAC_ID_BENGALI' : 13,
+ 'TT_MAC_ID_TAMIL' : 14,
+ 'TT_MAC_ID_TELUGU' : 15,
+ 'TT_MAC_ID_KANNADA' : 16,
+ 'TT_MAC_ID_MALAYALAM' : 17,
+ 'TT_MAC_ID_SINHALESE' : 18,
+ 'TT_MAC_ID_BURMESE' : 19,
+ 'TT_MAC_ID_KHMER' : 20,
+ 'TT_MAC_ID_THAI' : 21,
+ 'TT_MAC_ID_LAOTIAN' : 22,
+ 'TT_MAC_ID_GEORGIAN' : 23,
+ 'TT_MAC_ID_ARMENIAN' : 24,
+ 'TT_MAC_ID_MALDIVIAN' : 25,
+ 'TT_MAC_ID_SIMPLIFIED_CHINESE' : 25,
+ 'TT_MAC_ID_TIBETAN' : 26,
+ 'TT_MAC_ID_MONGOLIAN' : 27,
+ 'TT_MAC_ID_GEEZ' : 28,
+ 'TT_MAC_ID_SLAVIC' : 29,
+ 'TT_MAC_ID_VIETNAMESE' : 30,
+ 'TT_MAC_ID_SINDHI' : 31,
+ 'TT_MAC_ID_UNINTERP' : 32}
+globals().update(TT_MAC_IDS)
diff --git a/third_party/freetype-py/freetype/ft_enums/tt_mac_langids.py b/third_party/freetype-py/freetype/ft_enums/tt_mac_langids.py
new file mode 100644
index 0000000..2521aed
--- /dev/null
+++ b/third_party/freetype-py/freetype/ft_enums/tt_mac_langids.py
@@ -0,0 +1,376 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# -----------------------------------------------------------------------------
+#
+# FreeType high-level python API - Copyright 2011-2012 Nicolas P. Rougier
+# Distributed under the terms of the new BSD license.
+#
+# -----------------------------------------------------------------------------
+"""
+Possible values of the language identifier field in the name records of the
+TTF 'name' table if the 'platform' identifier code is TT_PLATFORM_MACINTOSH.
+
+TT_MAC_LANGID_LATIN
+
+TT_MAC_LANGID_MALAY_ARABIC_SCRIPT
+
+TT_MAC_LANGID_HINDI
+
+TT_MAC_LANGID_CATALAN
+
+TT_MAC_LANGID_MARATHI
+
+TT_MAC_LANGID_ICELANDIC
+
+TT_MAC_LANGID_ARABIC
+
+TT_MAC_LANGID_SWAHILI
+
+TT_MAC_LANGID_KHMER
+
+TT_MAC_LANGID_UKRAINIAN
+
+TT_MAC_LANGID_FINNISH
+
+TT_MAC_LANGID_POLISH
+
+TT_MAC_LANGID_NEPALI
+
+TT_MAC_LANGID_UZBEK
+
+TT_MAC_LANGID_TELUGU
+
+TT_MAC_LANGID_MALTESE
+
+TT_MAC_LANGID_AFRIKAANS
+
+TT_MAC_LANGID_CHEWA
+
+TT_MAC_LANGID_BASQUE
+
+TT_MAC_LANGID_CZECH
+
+TT_MAC_LANGID_ROMANIAN
+
+TT_MAC_LANGID_QUECHUA
+
+TT_MAC_LANGID_TAGALOG
+
+TT_MAC_LANGID_HUNGARIAN
+
+TT_MAC_LANGID_AZERBAIJANI_CYRILLIC_SCRIPT
+
+TT_MAC_LANGID_TONGAN
+
+TT_MAC_LANGID_SUNDANESE
+
+TT_MAC_LANGID_JAPANESE
+
+TT_MAC_LANGID_MONGOLIAN
+
+TT_MAC_LANGID_ALBANIAN
+
+TT_MAC_LANGID_NORWEGIAN
+
+TT_MAC_LANGID_SLOVAK
+
+TT_MAC_LANGID_MALAGASY
+
+TT_MAC_LANGID_DZONGKHA
+
+TT_MAC_LANGID_DUTCH
+
+TT_MAC_LANGID_MALAY_ROMAN_SCRIPT
+
+TT_MAC_LANGID_SERBIAN
+
+TT_MAC_LANGID_GERMAN
+
+TT_MAC_LANGID_SOMALI
+
+TT_MAC_LANGID_KOREAN
+
+TT_MAC_LANGID_MONGOLIAN_MONGOLIAN_SCRIPT
+
+TT_MAC_LANGID_CROATIAN
+
+TT_MAC_LANGID_TURKISH
+
+TT_MAC_LANGID_MOLDAVIAN
+
+TT_MAC_LANGID_LAO
+
+TT_MAC_LANGID_ORIYA
+
+TT_MAC_LANGID_BRETON
+
+TT_MAC_LANGID_PASHTO
+
+TT_MAC_LANGID_GUARANI
+
+TT_MAC_LANGID_HEBREW
+
+TT_MAC_LANGID_SLOVENIAN
+
+TT_MAC_LANGID_ESTONIAN
+
+TT_MAC_LANGID_RUNDI
+
+TT_MAC_LANGID_URDU
+
+TT_MAC_LANGID_CHINESE_TRADITIONAL
+
+TT_MAC_LANGID_TATAR
+
+TT_MAC_LANGID_CHINESE_SIMPLIFIED
+
+TT_MAC_LANGID_AZERBAIJANI_ARABIC_SCRIPT
+
+TT_MAC_LANGID_SANSKRIT
+
+TT_MAC_LANGID_KURDISH
+
+TT_MAC_LANGID_FAEROESE
+
+TT_MAC_LANGID_MONGOLIAN_CYRILLIC_SCRIPT
+
+TT_MAC_LANGID_TIGRINYA
+
+TT_MAC_LANGID_THAI
+
+TT_MAC_LANGID_DANISH
+
+TT_MAC_LANGID_KAZAKH
+
+TT_MAC_LANGID_YIDDISH
+
+TT_MAC_LANGID_ESPERANTO
+
+TT_MAC_LANGID_LITHUANIAN
+
+TT_MAC_LANGID_FARSI
+
+TT_MAC_LANGID_LETTISH
+
+TT_MAC_LANGID_VIETNAMESE
+
+TT_MAC_LANGID_PORTUGUESE
+
+TT_MAC_LANGID_IRISH
+
+TT_MAC_LANGID_WELSH
+
+TT_MAC_LANGID_PUNJABI
+
+TT_MAC_LANGID_GREEK
+
+TT_MAC_LANGID_INUKTITUT
+
+TT_MAC_LANGID_FRENCH
+
+TT_MAC_LANGID_GREEK_POLYTONIC
+
+TT_MAC_LANGID_AZERBAIJANI
+
+TT_MAC_LANGID_JAVANESE
+
+TT_MAC_LANGID_SWEDISH
+
+TT_MAC_LANGID_UIGHUR
+
+TT_MAC_LANGID_BENGALI
+
+TT_MAC_LANGID_RUANDA
+
+TT_MAC_LANGID_SINDHI
+
+TT_MAC_LANGID_TIBETAN
+
+TT_MAC_LANGID_ENGLISH
+
+TT_MAC_LANGID_SAAMISK
+
+TT_MAC_LANGID_INDONESIAN
+
+TT_MAC_LANGID_MANX_GAELIC
+
+TT_MAC_LANGID_BYELORUSSIAN
+
+TT_MAC_LANGID_BULGARIAN
+
+TT_MAC_LANGID_GEORGIAN
+
+TT_MAC_LANGID_AZERBAIJANI_ROMAN_SCRIPT
+
+TT_MAC_LANGID_ITALIAN
+
+TT_MAC_LANGID_SCOTTISH_GAELIC
+
+TT_MAC_LANGID_ARMENIAN
+
+TT_MAC_LANGID_GALLA
+
+TT_MAC_LANGID_MACEDONIAN
+
+TT_MAC_LANGID_IRISH_GAELIC
+
+TT_MAC_LANGID_KIRGHIZ
+
+TT_MAC_LANGID_TAMIL
+
+TT_MAC_LANGID_SPANISH
+
+TT_MAC_LANGID_BURMESE
+
+TT_MAC_LANGID_KANNADA
+
+TT_MAC_LANGID_GALICIAN
+
+TT_MAC_LANGID_FLEMISH
+
+TT_MAC_LANGID_TAJIKI
+
+TT_MAC_LANGID_ASSAMESE
+
+TT_MAC_LANGID_SINHALESE
+
+TT_MAC_LANGID_GREELANDIC
+
+TT_MAC_LANGID_AMHARIC
+
+TT_MAC_LANGID_KASHMIRI
+
+TT_MAC_LANGID_AYMARA
+
+TT_MAC_LANGID_GUJARATI
+
+TT_MAC_LANGID_RUSSIAN
+
+TT_MAC_LANGID_TURKMEN
+
+TT_MAC_LANGID_MALAYALAM
+"""
+TT_MAC_LANGIDS = {
+ 'TT_MAC_LANGID_ENGLISH' : 0,
+ 'TT_MAC_LANGID_FRENCH' : 1,
+ 'TT_MAC_LANGID_GERMAN' : 2,
+ 'TT_MAC_LANGID_ITALIAN' : 3,
+ 'TT_MAC_LANGID_DUTCH' : 4,
+ 'TT_MAC_LANGID_SWEDISH' : 5,
+ 'TT_MAC_LANGID_SPANISH' : 6,
+ 'TT_MAC_LANGID_DANISH' : 7,
+ 'TT_MAC_LANGID_PORTUGUESE' : 8,
+ 'TT_MAC_LANGID_NORWEGIAN' : 9,
+ 'TT_MAC_LANGID_HEBREW' : 10,
+ 'TT_MAC_LANGID_JAPANESE' : 11,
+ 'TT_MAC_LANGID_ARABIC' : 12,
+ 'TT_MAC_LANGID_FINNISH' : 13,
+ 'TT_MAC_LANGID_GREEK' : 14,
+ 'TT_MAC_LANGID_ICELANDIC' : 15,
+ 'TT_MAC_LANGID_MALTESE' : 16,
+ 'TT_MAC_LANGID_TURKISH' : 17,
+ 'TT_MAC_LANGID_CROATIAN' : 18,
+ 'TT_MAC_LANGID_CHINESE_TRADITIONAL' : 19,
+ 'TT_MAC_LANGID_URDU' : 20,
+ 'TT_MAC_LANGID_HINDI' : 21,
+ 'TT_MAC_LANGID_THAI' : 22,
+ 'TT_MAC_LANGID_KOREAN' : 23,
+ 'TT_MAC_LANGID_LITHUANIAN' : 24,
+ 'TT_MAC_LANGID_POLISH' : 25,
+ 'TT_MAC_LANGID_HUNGARIAN' : 26,
+ 'TT_MAC_LANGID_ESTONIAN' : 27,
+ 'TT_MAC_LANGID_LETTISH' : 28,
+ 'TT_MAC_LANGID_SAAMISK' : 29,
+ 'TT_MAC_LANGID_FAEROESE' : 30,
+ 'TT_MAC_LANGID_FARSI' : 31,
+ 'TT_MAC_LANGID_RUSSIAN' : 32,
+ 'TT_MAC_LANGID_CHINESE_SIMPLIFIED' : 33,
+ 'TT_MAC_LANGID_FLEMISH' : 34,
+ 'TT_MAC_LANGID_IRISH' : 35,
+ 'TT_MAC_LANGID_ALBANIAN' : 36,
+ 'TT_MAC_LANGID_ROMANIAN' : 37,
+ 'TT_MAC_LANGID_CZECH' : 38,
+ 'TT_MAC_LANGID_SLOVAK' : 39,
+ 'TT_MAC_LANGID_SLOVENIAN' : 40,
+ 'TT_MAC_LANGID_YIDDISH' : 41,
+ 'TT_MAC_LANGID_SERBIAN' : 42,
+ 'TT_MAC_LANGID_MACEDONIAN' : 43,
+ 'TT_MAC_LANGID_BULGARIAN' : 44,
+ 'TT_MAC_LANGID_UKRAINIAN' : 45,
+ 'TT_MAC_LANGID_BYELORUSSIAN' : 46,
+ 'TT_MAC_LANGID_UZBEK' : 47,
+ 'TT_MAC_LANGID_KAZAKH' : 48,
+ 'TT_MAC_LANGID_AZERBAIJANI' : 49,
+ 'TT_MAC_LANGID_AZERBAIJANI_CYRILLIC_SCRIPT': 49,
+ 'TT_MAC_LANGID_AZERBAIJANI_ARABIC_SCRIPT' : 50,
+ 'TT_MAC_LANGID_ARMENIAN' : 51,
+ 'TT_MAC_LANGID_GEORGIAN' : 52,
+ 'TT_MAC_LANGID_MOLDAVIAN' : 53,
+ 'TT_MAC_LANGID_KIRGHIZ' : 54,
+ 'TT_MAC_LANGID_TAJIKI' : 55,
+ 'TT_MAC_LANGID_TURKMEN' : 56,
+ 'TT_MAC_LANGID_MONGOLIAN' : 57,
+ 'TT_MAC_LANGID_MONGOLIAN_MONGOLIAN_SCRIPT' : 57,
+ 'TT_MAC_LANGID_MONGOLIAN_CYRILLIC_SCRIPT' : 58,
+ 'TT_MAC_LANGID_PASHTO' : 59,
+ 'TT_MAC_LANGID_KURDISH' : 60,
+ 'TT_MAC_LANGID_KASHMIRI' : 61,
+ 'TT_MAC_LANGID_SINDHI' : 62,
+ 'TT_MAC_LANGID_TIBETAN' : 63,
+ 'TT_MAC_LANGID_NEPALI' : 64,
+ 'TT_MAC_LANGID_SANSKRIT' : 65,
+ 'TT_MAC_LANGID_MARATHI' : 66,
+ 'TT_MAC_LANGID_BENGALI' : 67,
+ 'TT_MAC_LANGID_ASSAMESE' : 68,
+ 'TT_MAC_LANGID_GUJARATI' : 69,
+ 'TT_MAC_LANGID_PUNJABI' : 70,
+ 'TT_MAC_LANGID_ORIYA' : 71,
+ 'TT_MAC_LANGID_MALAYALAM' : 72,
+ 'TT_MAC_LANGID_KANNADA' : 73,
+ 'TT_MAC_LANGID_TAMIL' : 74,
+ 'TT_MAC_LANGID_TELUGU' : 75,
+ 'TT_MAC_LANGID_SINHALESE' : 76,
+ 'TT_MAC_LANGID_BURMESE' : 77,
+ 'TT_MAC_LANGID_KHMER' : 78,
+ 'TT_MAC_LANGID_LAO' : 79,
+ 'TT_MAC_LANGID_VIETNAMESE' : 80,
+ 'TT_MAC_LANGID_INDONESIAN' : 81,
+ 'TT_MAC_LANGID_TAGALOG' : 82,
+ 'TT_MAC_LANGID_MALAY_ROMAN_SCRIPT' : 83,
+ 'TT_MAC_LANGID_MALAY_ARABIC_SCRIPT' : 84,
+ 'TT_MAC_LANGID_AMHARIC' : 85,
+ 'TT_MAC_LANGID_TIGRINYA' : 86,
+ 'TT_MAC_LANGID_GALLA' : 87,
+ 'TT_MAC_LANGID_SOMALI' : 88,
+ 'TT_MAC_LANGID_SWAHILI' : 89,
+ 'TT_MAC_LANGID_RUANDA' : 90,
+ 'TT_MAC_LANGID_RUNDI' : 91,
+ 'TT_MAC_LANGID_CHEWA' : 92,
+ 'TT_MAC_LANGID_MALAGASY' : 93,
+ 'TT_MAC_LANGID_ESPERANTO' : 94,
+ 'TT_MAC_LANGID_WELSH' : 128,
+ 'TT_MAC_LANGID_BASQUE' : 129,
+ 'TT_MAC_LANGID_CATALAN' : 130,
+ 'TT_MAC_LANGID_LATIN' : 131,
+ 'TT_MAC_LANGID_QUECHUA' : 132,
+ 'TT_MAC_LANGID_GUARANI' : 133,
+ 'TT_MAC_LANGID_AYMARA' : 134,
+ 'TT_MAC_LANGID_TATAR' : 135,
+ 'TT_MAC_LANGID_UIGHUR' : 136,
+ 'TT_MAC_LANGID_DZONGKHA' : 137,
+ 'TT_MAC_LANGID_JAVANESE' : 138,
+ 'TT_MAC_LANGID_SUNDANESE' : 139,
+ 'TT_MAC_LANGID_GALICIAN' : 140,
+ 'TT_MAC_LANGID_AFRIKAANS' : 141,
+ 'TT_MAC_LANGID_BRETON' : 142,
+ 'TT_MAC_LANGID_INUKTITUT' : 143,
+ 'TT_MAC_LANGID_SCOTTISH_GAELIC' : 144,
+ 'TT_MAC_LANGID_MANX_GAELIC' : 145,
+ 'TT_MAC_LANGID_IRISH_GAELIC' : 146,
+ 'TT_MAC_LANGID_TONGAN' : 147,
+ 'TT_MAC_LANGID_GREEK_POLYTONIC' : 148,
+ 'TT_MAC_LANGID_GREELANDIC' : 149,
+ 'TT_MAC_LANGID_AZERBAIJANI_ROMAN_SCRIPT' : 150 }
+globals().update(TT_MAC_LANGIDS)
+
+
diff --git a/third_party/freetype-py/freetype/ft_enums/tt_ms_ids.py b/third_party/freetype-py/freetype/ft_enums/tt_ms_ids.py
new file mode 100644
index 0000000..43b0af8
--- /dev/null
+++ b/third_party/freetype-py/freetype/ft_enums/tt_ms_ids.py
@@ -0,0 +1,68 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# -----------------------------------------------------------------------------
+#
+# FreeType high-level python API - Copyright 2011-2012 Nicolas P. Rougier
+# Distributed under the terms of the new BSD license.
+#
+# -----------------------------------------------------------------------------
+"""
+A list of valid values for the 'encoding_id' for TT_PLATFORM_MICROSOFT
+charmaps and name entries.
+
+
+TT_MS_ID_SYMBOL_CS
+
+ Corresponds to Microsoft symbol encoding. See FT_ENCODING_MS_SYMBOL.
+
+
+TT_MS_ID_UNICODE_CS
+
+ Corresponds to a Microsoft WGL4 charmap, matching Unicode. See
+ FT_ENCODING_UNICODE.
+
+
+TT_MS_ID_SJIS
+
+ Corresponds to SJIS Japanese encoding. See FT_ENCODING_SJIS.
+
+
+TT_MS_ID_GB2312
+
+ Corresponds to Simplified Chinese as used in Mainland China. See
+ FT_ENCODING_GB2312.
+
+
+TT_MS_ID_BIG_5
+
+ Corresponds to Traditional Chinese as used in Taiwan and Hong Kong. See
+ FT_ENCODING_BIG5.
+
+
+TT_MS_ID_WANSUNG
+
+ Corresponds to Korean Wansung encoding. See FT_ENCODING_WANSUNG.
+
+TT_MS_ID_JOHAB
+
+ Corresponds to Johab encoding. See FT_ENCODING_JOHAB.
+
+
+TT_MS_ID_UCS_4
+
+ Corresponds to UCS-4 or UTF-32 charmaps. This has been added to the OpenType
+ specification version 1.4 (mid-2001.)
+"""
+
+TT_MS_IDS = {
+ 'TT_MS_ID_SYMBOL_CS' : 0,
+ 'TT_MS_ID_UNICODE_CS' : 1,
+ 'TT_MS_ID_SJIS' : 2,
+ 'TT_MS_ID_GB2312' : 3,
+ 'TT_MS_ID_BIG_5' : 4,
+ 'TT_MS_ID_WANSUNG' : 5,
+ 'TT_MS_ID_JOHAB' : 6,
+ 'TT_MS_ID_UCS_4' : 10 }
+globals().update(TT_MS_IDS)
+
+
diff --git a/third_party/freetype-py/freetype/ft_enums/tt_ms_langids.py b/third_party/freetype-py/freetype/ft_enums/tt_ms_langids.py
new file mode 100644
index 0000000..7258b58
--- /dev/null
+++ b/third_party/freetype-py/freetype/ft_enums/tt_ms_langids.py
@@ -0,0 +1,751 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# -----------------------------------------------------------------------------
+#
+# FreeType high-level python API - Copyright 2011-2012 Nicolas P. Rougier
+# Distributed under the terms of the new BSD license.
+#
+# -----------------------------------------------------------------------------
+"""
+Possible values of the language identifier field in the name records of the
+TTF 'name' table if the 'platform' identifier code is TT_PLATFORM_MICROSOFT.
+
+TT_MS_LANGID_SANSKRIT_INDIA
+
+TT_MS_LANGID_ENGLISH_UNITED_KINGDOM
+
+TT_MS_LANGID_ENGLISH_BELIZE
+
+TT_MS_LANGID_ARABIC_LEBANON
+
+TT_MS_LANGID_MOLDAVIAN_MOLDAVIA
+
+TT_MS_LANGID_TURKISH_TURKEY
+
+TT_MS_LANGID_WELSH_WALES
+
+TT_MS_LANGID_GERMAN_AUSTRIA
+
+TT_MS_LANGID_DUTCH_BELGIUM
+
+TT_MS_LANGID_YI_CHINA
+
+TT_MS_LANGID_QUECHUA_ECUADOR
+
+TT_MS_LANGID_SPANISH_EL_SALVADOR
+
+TT_MS_LANGID_SWAHILI_KENYA
+
+TT_MS_LANGID_QUECHUA_BOLIVIA
+
+TT_MS_LANGID_SLOVENE_SLOVENIA
+
+TT_MS_LANGID_ORIYA_INDIA
+
+TT_MS_LANGID_FARSI_IRAN
+
+TT_MS_LANGID_ENGLISH_CANADA
+
+TT_MS_LANGID_NEPALI_NEPAL
+
+TT_MS_LANGID_DHIVEHI_MALDIVES
+
+TT_MS_LANGID_GERMAN_LIECHTENSTEI
+
+TT_MS_LANGID_TAMIL_INDIA
+
+TT_MS_LANGID_ARABIC_UAE
+
+TT_MS_LANGID_JAPANESE_JAPAN
+
+TT_MS_LANGID_TAMAZIGHT_MOROCCO
+
+TT_MS_LANGID_FRENCH_FRANCE
+
+TT_MS_LANGID_CHINESE_MACAU
+
+TT_MS_LANGID_VIETNAMESE_VIET_NAM
+
+TT_MS_LANGID_HEBREW_ISRAEL
+
+TT_MS_LANGID_SAMI_NORTHERN_SWEDEN
+
+TT_MS_LANGID_PUNJABI_ARABIC_PAKISTAN
+
+TT_MS_LANGID_SWEDISH_SWEDEN
+
+TT_MS_LANGID_FRENCH_REUNION
+
+TT_MS_LANGID_ARABIC_BAHRAIN
+
+TT_MS_LANGID_ENGLISH_INDIA
+
+TT_MS_LANGID_NEPALI_INDIA
+
+TT_MS_LANGID_THAI_THAILAND
+
+TT_MS_LANGID_ENGLISH_GENERAL
+
+TT_MS_LANGID_SAMI_LULE_NORWAY
+
+TT_MS_LANGID_ARABIC_OMAN
+
+TT_MS_LANGID_SPANISH_HONDURAS
+
+TT_MS_LANGID_ENGLISH_JAMAICA
+
+TT_MS_LANGID_ESTONIAN_ESTONIA
+
+TT_MS_LANGID_FRISIAN_NETHERLANDS
+
+TT_MS_LANGID_LATIN
+
+TT_MS_LANGID_ENGLISH_INDONESIA
+
+TT_MS_LANGID_ENGLISH_IRELAND
+
+TT_MS_LANGID_TIBETAN_CHINA
+
+TT_MS_LANGID_PUNJABI_INDIA
+
+TT_MS_LANGID_FRENCH_MALI
+
+TT_MS_LANGID_GERMAN_LUXEMBOURG
+
+TT_MS_LANGID_SUTU_SOUTH_AFRICA
+
+TT_MS_LANGID_FRENCH_CAMEROON
+
+TT_MS_LANGID_FRENCH_CONGO
+
+TT_MS_LANGID_CLASSIC_LITHUANIAN_LITHUANIA
+
+TT_MS_LANGID_MALAYALAM_INDIA
+
+TT_MS_LANGID_SAMI_SOUTHERN_SWEDEN
+
+TT_MS_LANGID_CHEROKEE_UNITED_STATES
+
+TT_MS_LANGID_SPANISH_GUATEMALA
+
+TT_MS_LANGID_CZECH_CZECH_REPUBLIC
+
+TT_MS_LANGID_MANIPURI_INDIA
+
+TT_MS_LANGID_ENGLISH_AUSTRALIA
+
+TT_MS_LANGID_SPANISH_DOMINICAN_REPUBLIC
+
+TT_MS_LANGID_ARABIC_LIBYA
+
+TT_MS_LANGID_FRENCH_WEST_INDIES
+
+TT_MS_LANGID_ENGLISH_TRINIDAD
+
+TT_MS_LANGID_ARABIC_QATAR
+
+TT_MS_LANGID_SPANISH_COLOMBIA
+
+TT_MS_LANGID_GUARANI_PARAGUAY
+
+TT_MS_LANGID_EDO_NIGERIA
+
+TT_MS_LANGID_SEPEDI_SOUTH_AFRICA
+
+TT_MS_LANGID_ENGLISH_HONG_KONG
+
+TT_MS_LANGID_KOREAN_EXTENDED_WANSUNG_KOREA
+
+TT_MS_LANGID_TATAR_TATARSTAN
+
+TT_MS_LANGID_PASHTO_AFGHANISTAN
+
+TT_MS_LANGID_KASHMIRI_PAKISTAN
+
+TT_MS_LANGID_GALICIAN_SPAIN
+
+TT_MS_LANGID_TAJIK_TAJIKISTAN
+
+TT_MS_LANGID_SAMI_INARI_FINLAND
+
+TT_MS_LANGID_KASHMIRI_SASIA
+
+TT_MS_LANGID_SPANISH_ARGENTINA
+
+TT_MS_LANGID_SAMI_SOUTHERN_NORWAY
+
+TT_MS_LANGID_CROATIAN_CROATIA
+
+TT_MS_LANGID_GUJARATI_INDIA
+
+TT_MS_LANGID_TIBETAN_BHUTAN
+
+TT_MS_LANGID_TIGRIGNA_ETHIOPIA
+
+TT_MS_LANGID_FINNISH_FINLAND
+
+TT_MS_LANGID_ENGLISH_UNITED_STATES
+
+TT_MS_LANGID_ITALIAN_SWITZERLAND
+
+TT_MS_LANGID_ARABIC_EGYPT
+
+TT_MS_LANGID_SPANISH_LATIN_AMERICA
+
+TT_MS_LANGID_LITHUANIAN_LITHUANIA
+
+TT_MS_LANGID_ARABIC_ALGERIA
+
+TT_MS_LANGID_MALAY_MALAYSIA
+
+TT_MS_LANGID_ARABIC_GENERAL
+
+TT_MS_LANGID_CHINESE_PRC
+
+TT_MS_LANGID_BENGALI_BANGLADESH
+
+TT_MS_LANGID_SPANISH_PERU
+
+TT_MS_LANGID_SPANISH_SPAIN_INTERNATIONAL_SORT
+
+TT_MS_LANGID_DIVEHI_MALDIVES
+
+TT_MS_LANGID_LATVIAN_LATVIA
+
+TT_MS_LANGID_TURKMEN_TURKMENISTAN
+
+TT_MS_LANGID_XHOSA_SOUTH_AFRICA
+
+TT_MS_LANGID_KHMER_CAMBODIA
+
+TT_MS_LANGID_NORWEGIAN_NORWAY_NYNORSK
+
+TT_MS_LANGID_ARABIC_MOROCCO
+
+TT_MS_LANGID_FRENCH_SENEGAL
+
+TT_MS_LANGID_YORUBA_NIGERIA
+
+TT_MS_LANGID_CATALAN_SPAIN
+
+TT_MS_LANGID_AFRIKAANS_SOUTH_AFRICA
+
+TT_MS_LANGID_ZULU_SOUTH_AFRICA
+
+TT_MS_LANGID_SPANISH_URUGUAY
+
+TT_MS_LANGID_SPANISH_ECUADOR
+
+TT_MS_LANGID_BOSNIAN_BOSNIA_HERZEGOVINA
+
+TT_MS_LANGID_CHINESE_GENERAL
+
+TT_MS_LANGID_SPANISH_PARAGUAY
+
+TT_MS_LANGID_HINDI_INDIA
+
+TT_MS_LANGID_FRENCH_LUXEMBOURG
+
+TT_MS_LANGID_TSWANA_SOUTH_AFRICA
+
+TT_MS_LANGID_HUNGARIAN_HUNGARY
+
+TT_MS_LANGID_CROATIAN_BOSNIA_HERZEGOVINA
+
+TT_MS_LANGID_ENGLISH_SINGAPORE
+
+TT_MS_LANGID_MALTESE_MALTA
+
+TT_MS_LANGID_SAMI_NORTHERN_FINLAND
+
+TT_MS_LANGID_FRENCH_CANADA
+
+TT_MS_LANGID_SAMI_LULE_SWEDEN
+
+TT_MS_LANGID_KANURI_NIGERIA
+
+TT_MS_LANGID_IRISH_GAELIC_IRELAND
+
+TT_MS_LANGID_ARABIC_SAUDI_ARABIA
+
+TT_MS_LANGID_FRENCH_HAITI
+
+TT_MS_LANGID_SPANISH_PUERTO_RICO
+
+TT_MS_LANGID_BURMESE_MYANMAR
+
+TT_MS_LANGID_POLISH_POLAND
+
+TT_MS_LANGID_PORTUGUESE_PORTUGAL
+
+TT_MS_LANGID_ENGLISH_CARIBBEAN
+
+TT_MS_LANGID_KIRGHIZ_KIRGHIZ_REPUBLIC
+
+TT_MS_LANGID_ICELANDIC_ICELAND
+
+TT_MS_LANGID_BENGALI_INDIA
+
+TT_MS_LANGID_HAUSA_NIGERIA
+
+TT_MS_LANGID_BASQUE_SPAIN
+
+TT_MS_LANGID_UIGHUR_CHINA
+
+TT_MS_LANGID_ENGLISH_MALAYSIA
+
+TT_MS_LANGID_FRENCH_MONACO
+
+TT_MS_LANGID_SPANISH_BOLIVIA
+
+TT_MS_LANGID_SORBIAN_GERMANY
+
+TT_MS_LANGID_SINDHI_INDIA
+
+TT_MS_LANGID_CHINESE_SINGAPORE
+
+TT_MS_LANGID_FRENCH_COTE_D_IVOIRE
+
+TT_MS_LANGID_SPANISH_SPAIN_TRADITIONAL_SORT
+
+TT_MS_LANGID_SERBIAN_SERBIA_CYRILLIC
+
+TT_MS_LANGID_SAMI_SKOLT_FINLAND
+
+TT_MS_LANGID_SERBIAN_BOSNIA_HERZ_CYRILLIC
+
+TT_MS_LANGID_MALAY_BRUNEI_DARUSSALAM
+
+TT_MS_LANGID_ARABIC_JORDAN
+
+TT_MS_LANGID_MONGOLIAN_MONGOLIA_MONGOLIAN
+
+TT_MS_LANGID_SERBIAN_SERBIA_LATIN
+
+TT_MS_LANGID_RUSSIAN_RUSSIA
+
+TT_MS_LANGID_ROMANIAN_ROMANIA
+
+TT_MS_LANGID_FRENCH_NORTH_AFRICA
+
+TT_MS_LANGID_MONGOLIAN_MONGOLIA
+
+TT_MS_LANGID_TSONGA_SOUTH_AFRICA
+
+TT_MS_LANGID_SOMALI_SOMALIA
+
+TT_MS_LANGID_SAAMI_LAPONIA
+
+TT_MS_LANGID_SPANISH_COSTA_RICA
+
+TT_MS_LANGID_ARABIC_SYRIA
+
+TT_MS_LANGID_SPANISH_PANAMA
+
+TT_MS_LANGID_PAPIAMENTU_NETHERLANDS_ANTILLES
+
+TT_MS_LANGID_ASSAMESE_INDIA
+
+TT_MS_LANGID_SCOTTISH_GAELIC_UNITED_KINGDOM
+
+TT_MS_LANGID_DUTCH_NETHERLANDS
+
+TT_MS_LANGID_SINDHI_PAKISTAN
+
+TT_MS_LANGID_MACEDONIAN_MACEDONIA
+
+TT_MS_LANGID_KAZAK_KAZAKSTAN
+
+TT_MS_LANGID_AZERI_AZERBAIJAN_LATIN
+
+TT_MS_LANGID_BELARUSIAN_BELARUS
+
+TT_MS_LANGID_FRENCH_MOROCCO
+
+TT_MS_LANGID_SERBIAN_BOSNIA_HERZ_LATIN
+
+TT_MS_LANGID_ALBANIAN_ALBANIA
+
+TT_MS_LANGID_SINHALESE_SRI_LANKA
+
+TT_MS_LANGID_SPANISH_MEXICO
+
+TT_MS_LANGID_ENGLISH_ZIMBABWE
+
+TT_MS_LANGID_OROMO_ETHIOPIA
+
+TT_MS_LANGID_INDONESIAN_INDONESIA
+
+TT_MS_LANGID_SAMI_NORTHERN_NORWAY
+
+TT_MS_LANGID_UZBEK_UZBEKISTAN_LATIN
+
+TT_MS_LANGID_SLOVAK_SLOVAKIA
+
+TT_MS_LANGID_KASHMIRI_INDIA
+
+TT_MS_LANGID_GERMAN_SWITZERLAND
+
+TT_MS_LANGID_URDU_INDIA
+
+TT_MS_LANGID_FAEROESE_FAEROE_ISLANDS
+
+TT_MS_LANGID_SYRIAC_SYRIA
+
+TT_MS_LANGID_SPANISH_CHILE
+
+TT_MS_LANGID_FILIPINO_PHILIPPINES
+
+TT_MS_LANGID_ARABIC_YEMEN
+
+TT_MS_LANGID_KONKANI_INDIA
+
+TT_MS_LANGID_AMHARIC_ETHIOPIA
+
+TT_MS_LANGID_ENGLISH_NEW_ZEALAND
+
+TT_MS_LANGID_RHAETO_ROMANIC_SWITZERLAND
+
+TT_MS_LANGID_ARABIC_TUNISIA
+
+TT_MS_LANGID_SOTHO_SOUTHERN_SOUTH_AFRICA
+
+TT_MS_LANGID_QUECHUA_PERU
+
+TT_MS_LANGID_DANISH_DENMARK
+
+TT_MS_LANGID_ENGLISH_PHILIPPINES
+
+TT_MS_LANGID_SPANISH_NICARAGUA
+
+TT_MS_LANGID_INUKTITUT_CANADA
+
+TT_MS_LANGID_UKRAINIAN_UKRAINE
+
+TT_MS_LANGID_NORWEGIAN_NORWAY_BOKMAL
+
+TT_MS_LANGID_UZBEK_UZBEKISTAN_CYRILLIC
+
+TT_MS_LANGID_FRENCH_BELGIUM
+
+TT_MS_LANGID_ENGLISH_SOUTH_AFRICA
+
+TT_MS_LANGID_HAWAIIAN_UNITED_STATES
+
+TT_MS_LANGID_ARABIC_IRAQ
+
+TT_MS_LANGID_KANNADA_INDIA
+
+TT_MS_LANGID_DZONGHKA_BHUTAN
+
+TT_MS_LANGID_CHINESE_TAIWAN
+
+TT_MS_LANGID_SPANISH_UNITED_STATES
+
+TT_MS_LANGID_ARMENIAN_ARMENIA
+
+TT_MS_LANGID_LAO_LAOS
+
+TT_MS_LANGID_TIGRIGNA_ERYTREA
+
+TT_MS_LANGID_MARATHI_INDIA
+
+TT_MS_LANGID_ARABIC_KUWAIT
+
+TT_MS_LANGID_TAMAZIGHT_MOROCCO_LATIN
+
+TT_MS_LANGID_PORTUGUESE_BRAZIL
+
+TT_MS_LANGID_TIGRIGNA_ERYTHREA
+
+TT_MS_LANGID_GREEK_GREECE
+
+TT_MS_LANGID_URDU_PAKISTAN
+
+TT_MS_LANGID_KIRGHIZ_KIRGHIZSTAN
+
+TT_MS_LANGID_YIDDISH_GERMANY
+
+TT_MS_LANGID_GERMAN_GERMANY
+
+TT_MS_LANGID_TELUGU_INDIA
+
+TT_MS_LANGID_AZERI_AZERBAIJAN_CYRILLIC
+
+TT_MS_LANGID_KOREAN_JOHAB_KOREA
+
+TT_MS_LANGID_ITALIAN_ITALY
+
+TT_MS_LANGID_MAORI_NEW_ZEALAND
+
+TT_MS_LANGID_SPANISH_VENEZUELA
+
+TT_MS_LANGID_IGBO_NIGERIA
+
+TT_MS_LANGID_IBIBIO_NIGERIA
+
+TT_MS_LANGID_CHINESE_HONG_KONG
+
+TT_MS_LANGID_FRENCH_SWITZERLAND
+
+TT_MS_LANGID_BULGARIAN_BULGARIA
+
+TT_MS_LANGID_FULFULDE_NIGERIA
+
+TT_MS_LANGID_RUSSIAN_MOLDAVIA
+
+TT_MS_LANGID_VENDA_SOUTH_AFRICA
+
+TT_MS_LANGID_GEORGIAN_GEORGIA
+
+TT_MS_LANGID_SWEDISH_FINLAND
+"""
+
+TT_MS_LANGIDS = {
+ 'TT_MS_LANGID_ARABIC_GENERAL' : 0x0001,
+ 'TT_MS_LANGID_ARABIC_SAUDI_ARABIA' : 0x0401,
+ 'TT_MS_LANGID_ARABIC_IRAQ' : 0x0801,
+ 'TT_MS_LANGID_ARABIC_EGYPT' : 0x0c01,
+ 'TT_MS_LANGID_ARABIC_LIBYA' : 0x1001,
+ 'TT_MS_LANGID_ARABIC_ALGERIA' : 0x1401,
+ 'TT_MS_LANGID_ARABIC_MOROCCO' : 0x1801,
+ 'TT_MS_LANGID_ARABIC_TUNISIA' : 0x1c01,
+ 'TT_MS_LANGID_ARABIC_OMAN' : 0x2001,
+ 'TT_MS_LANGID_ARABIC_YEMEN' : 0x2401,
+ 'TT_MS_LANGID_ARABIC_SYRIA' : 0x2801,
+ 'TT_MS_LANGID_ARABIC_JORDAN' : 0x2c01,
+ 'TT_MS_LANGID_ARABIC_LEBANON' : 0x3001,
+ 'TT_MS_LANGID_ARABIC_KUWAIT' : 0x3401,
+ 'TT_MS_LANGID_ARABIC_UAE' : 0x3801,
+ 'TT_MS_LANGID_ARABIC_BAHRAIN' : 0x3c01,
+ 'TT_MS_LANGID_ARABIC_QATAR' : 0x4001,
+ 'TT_MS_LANGID_BULGARIAN_BULGARIA' : 0x0402,
+ 'TT_MS_LANGID_CATALAN_SPAIN' : 0x0403,
+ 'TT_MS_LANGID_CHINESE_GENERAL' : 0x0004,
+ 'TT_MS_LANGID_CHINESE_TAIWAN' : 0x0404,
+ 'TT_MS_LANGID_CHINESE_PRC' : 0x0804,
+ 'TT_MS_LANGID_CHINESE_HONG_KONG' : 0x0c04,
+ 'TT_MS_LANGID_CHINESE_SINGAPORE' : 0x1004,
+ 'TT_MS_LANGID_CHINESE_MACAU' : 0x1404,
+ 'TT_MS_LANGID_CZECH_CZECH_REPUBLIC' : 0x0405,
+ 'TT_MS_LANGID_DANISH_DENMARK' : 0x0406,
+ 'TT_MS_LANGID_GERMAN_GERMANY' : 0x0407,
+ 'TT_MS_LANGID_GERMAN_SWITZERLAND' : 0x0807,
+ 'TT_MS_LANGID_GERMAN_AUSTRIA' : 0x0c07,
+ 'TT_MS_LANGID_GERMAN_LUXEMBOURG' : 0x1007,
+ 'TT_MS_LANGID_GERMAN_LIECHTENSTEI' : 0x1407,
+ 'TT_MS_LANGID_GREEK_GREECE' : 0x0408,
+ 'TT_MS_LANGID_ENGLISH_GENERAL' : 0x0009,
+ 'TT_MS_LANGID_ENGLISH_UNITED_STATES' : 0x0409,
+ 'TT_MS_LANGID_ENGLISH_UNITED_KINGDOM' : 0x0809,
+ 'TT_MS_LANGID_ENGLISH_AUSTRALIA' : 0x0c09,
+ 'TT_MS_LANGID_ENGLISH_CANADA' : 0x1009,
+ 'TT_MS_LANGID_ENGLISH_NEW_ZEALAND' : 0x1409,
+ 'TT_MS_LANGID_ENGLISH_IRELAND' : 0x1809,
+ 'TT_MS_LANGID_ENGLISH_SOUTH_AFRICA' : 0x1c09,
+ 'TT_MS_LANGID_ENGLISH_JAMAICA' : 0x2009,
+ 'TT_MS_LANGID_ENGLISH_CARIBBEAN' : 0x2409,
+ 'TT_MS_LANGID_ENGLISH_BELIZE' : 0x2809,
+ 'TT_MS_LANGID_ENGLISH_TRINIDAD' : 0x2c09,
+ 'TT_MS_LANGID_ENGLISH_ZIMBABWE' : 0x3009,
+ 'TT_MS_LANGID_ENGLISH_PHILIPPINES' : 0x3409,
+ 'TT_MS_LANGID_ENGLISH_INDONESIA' : 0x3809,
+ 'TT_MS_LANGID_ENGLISH_HONG_KONG' : 0x3c09,
+ 'TT_MS_LANGID_ENGLISH_INDIA' : 0x4009,
+ 'TT_MS_LANGID_ENGLISH_MALAYSIA' : 0x4409,
+ 'TT_MS_LANGID_ENGLISH_SINGAPORE' : 0x4809,
+ 'TT_MS_LANGID_SPANISH_SPAIN_TRADITIONAL_SORT' : 0x040a,
+ 'TT_MS_LANGID_SPANISH_MEXICO' : 0x080a,
+ 'TT_MS_LANGID_SPANISH_SPAIN_INTERNATIONAL_SORT' : 0x0c0a,
+ 'TT_MS_LANGID_SPANISH_GUATEMALA' : 0x100a,
+ 'TT_MS_LANGID_SPANISH_COSTA_RICA' : 0x140a,
+ 'TT_MS_LANGID_SPANISH_PANAMA' : 0x180a,
+ 'TT_MS_LANGID_SPANISH_DOMINICAN_REPUBLIC' : 0x1c0a,
+ 'TT_MS_LANGID_SPANISH_VENEZUELA' : 0x200a,
+ 'TT_MS_LANGID_SPANISH_COLOMBIA' : 0x240a,
+ 'TT_MS_LANGID_SPANISH_PERU' : 0x280a,
+ 'TT_MS_LANGID_SPANISH_ARGENTINA' : 0x2c0a,
+ 'TT_MS_LANGID_SPANISH_ECUADOR' : 0x300a,
+ 'TT_MS_LANGID_SPANISH_CHILE' : 0x340a,
+ 'TT_MS_LANGID_SPANISH_URUGUAY' : 0x380a,
+ 'TT_MS_LANGID_SPANISH_PARAGUAY' : 0x3c0a,
+ 'TT_MS_LANGID_SPANISH_BOLIVIA' : 0x400a,
+ 'TT_MS_LANGID_SPANISH_EL_SALVADOR' : 0x440a,
+ 'TT_MS_LANGID_SPANISH_HONDURAS' : 0x480a,
+ 'TT_MS_LANGID_SPANISH_NICARAGUA' : 0x4c0a,
+ 'TT_MS_LANGID_SPANISH_PUERTO_RICO' : 0x500a,
+ 'TT_MS_LANGID_SPANISH_UNITED_STATES' : 0x540a,
+ 'TT_MS_LANGID_SPANISH_LATIN_AMERICA' : 0xE40a,
+ 'TT_MS_LANGID_FINNISH_FINLAND' : 0x040b,
+ 'TT_MS_LANGID_FRENCH_FRANCE' : 0x040c,
+ 'TT_MS_LANGID_FRENCH_BELGIUM' : 0x080c,
+ 'TT_MS_LANGID_FRENCH_CANADA' : 0x0c0c,
+ 'TT_MS_LANGID_FRENCH_SWITZERLAND' : 0x100c,
+ 'TT_MS_LANGID_FRENCH_LUXEMBOURG' : 0x140c,
+ 'TT_MS_LANGID_FRENCH_MONACO' : 0x180c,
+ 'TT_MS_LANGID_FRENCH_WEST_INDIES' : 0x1c0c,
+ 'TT_MS_LANGID_FRENCH_REUNION' : 0x200c,
+ 'TT_MS_LANGID_FRENCH_CONGO' : 0x240c,
+ 'TT_MS_LANGID_FRENCH_SENEGAL' : 0x280c,
+ 'TT_MS_LANGID_FRENCH_CAMEROON' : 0x2c0c,
+ 'TT_MS_LANGID_FRENCH_COTE_D_IVOIRE' : 0x300c,
+ 'TT_MS_LANGID_FRENCH_MALI' : 0x340c,
+ 'TT_MS_LANGID_FRENCH_MOROCCO' : 0x380c,
+ 'TT_MS_LANGID_FRENCH_HAITI' : 0x3c0c,
+ 'TT_MS_LANGID_FRENCH_NORTH_AFRICA' : 0xE40c,
+ 'TT_MS_LANGID_HEBREW_ISRAEL' : 0x040d,
+ 'TT_MS_LANGID_HUNGARIAN_HUNGARY' : 0x040e,
+ 'TT_MS_LANGID_ICELANDIC_ICELAND' : 0x040f,
+ 'TT_MS_LANGID_ITALIAN_ITALY' : 0x0410,
+ 'TT_MS_LANGID_ITALIAN_SWITZERLAND' : 0x0810,
+ 'TT_MS_LANGID_JAPANESE_JAPAN' : 0x0411,
+ 'TT_MS_LANGID_KOREAN_EXTENDED_WANSUNG_KOREA' : 0x0412,
+ 'TT_MS_LANGID_KOREAN_JOHAB_KOREA' : 0x0812,
+ 'TT_MS_LANGID_DUTCH_NETHERLANDS' : 0x0413,
+ 'TT_MS_LANGID_DUTCH_BELGIUM' : 0x0813,
+ 'TT_MS_LANGID_NORWEGIAN_NORWAY_BOKMAL' : 0x0414,
+ 'TT_MS_LANGID_NORWEGIAN_NORWAY_NYNORSK' : 0x0814,
+ 'TT_MS_LANGID_POLISH_POLAND' : 0x0415,
+ 'TT_MS_LANGID_PORTUGUESE_BRAZIL' : 0x0416,
+ 'TT_MS_LANGID_PORTUGUESE_PORTUGAL' : 0x0816,
+ 'TT_MS_LANGID_RHAETO_ROMANIC_SWITZERLAND' : 0x0417,
+ 'TT_MS_LANGID_ROMANIAN_ROMANIA' : 0x0418,
+ 'TT_MS_LANGID_MOLDAVIAN_MOLDAVIA' : 0x0818,
+ 'TT_MS_LANGID_RUSSIAN_RUSSIA' : 0x0419,
+ 'TT_MS_LANGID_RUSSIAN_MOLDAVIA' : 0x0819,
+ 'TT_MS_LANGID_CROATIAN_CROATIA' : 0x041a,
+ 'TT_MS_LANGID_SERBIAN_SERBIA_LATIN' : 0x081a,
+ 'TT_MS_LANGID_SERBIAN_SERBIA_CYRILLIC' : 0x0c1a,
+ 'TT_MS_LANGID_CROATIAN_BOSNIA_HERZEGOVINA' : 0x101a,
+ 'TT_MS_LANGID_BOSNIAN_BOSNIA_HERZEGOVINA' : 0x141a,
+ 'TT_MS_LANGID_SERBIAN_BOSNIA_HERZ_LATIN' : 0x181a,
+ 'TT_MS_LANGID_SERBIAN_BOSNIA_HERZ_CYRILLIC' : 0x181a,
+ 'TT_MS_LANGID_SLOVAK_SLOVAKIA' : 0x041b,
+ 'TT_MS_LANGID_ALBANIAN_ALBANIA' : 0x041c,
+ 'TT_MS_LANGID_SWEDISH_SWEDEN' : 0x041d,
+ 'TT_MS_LANGID_SWEDISH_FINLAND' : 0x081d,
+ 'TT_MS_LANGID_THAI_THAILAND' : 0x041e,
+ 'TT_MS_LANGID_TURKISH_TURKEY' : 0x041f,
+ 'TT_MS_LANGID_URDU_PAKISTAN' : 0x0420,
+ 'TT_MS_LANGID_URDU_INDIA' : 0x0820,
+ 'TT_MS_LANGID_INDONESIAN_INDONESIA' : 0x0421,
+ 'TT_MS_LANGID_UKRAINIAN_UKRAINE' : 0x0422,
+ 'TT_MS_LANGID_BELARUSIAN_BELARUS' : 0x0423,
+ 'TT_MS_LANGID_SLOVENE_SLOVENIA' : 0x0424,
+ 'TT_MS_LANGID_ESTONIAN_ESTONIA' : 0x0425,
+ 'TT_MS_LANGID_LATVIAN_LATVIA' : 0x0426,
+ 'TT_MS_LANGID_LITHUANIAN_LITHUANIA' : 0x0427,
+ 'TT_MS_LANGID_CLASSIC_LITHUANIAN_LITHUANIA' : 0x0827,
+ 'TT_MS_LANGID_TAJIK_TAJIKISTAN' : 0x0428,
+ 'TT_MS_LANGID_FARSI_IRAN' : 0x0429,
+ 'TT_MS_LANGID_VIETNAMESE_VIET_NAM' : 0x042a,
+ 'TT_MS_LANGID_ARMENIAN_ARMENIA' : 0x042b,
+ 'TT_MS_LANGID_AZERI_AZERBAIJAN_LATIN' : 0x042c,
+ 'TT_MS_LANGID_AZERI_AZERBAIJAN_CYRILLIC' : 0x082c,
+ 'TT_MS_LANGID_BASQUE_SPAIN' : 0x042d,
+ 'TT_MS_LANGID_SORBIAN_GERMANY' : 0x042e,
+ 'TT_MS_LANGID_MACEDONIAN_MACEDONIA' : 0x042f,
+ 'TT_MS_LANGID_SUTU_SOUTH_AFRICA' : 0x0430,
+ 'TT_MS_LANGID_TSONGA_SOUTH_AFRICA' : 0x0431,
+ 'TT_MS_LANGID_TSWANA_SOUTH_AFRICA' : 0x0432,
+ 'TT_MS_LANGID_VENDA_SOUTH_AFRICA' : 0x0433,
+ 'TT_MS_LANGID_XHOSA_SOUTH_AFRICA' : 0x0434,
+ 'TT_MS_LANGID_ZULU_SOUTH_AFRICA' : 0x0435,
+ 'TT_MS_LANGID_AFRIKAANS_SOUTH_AFRICA' : 0x0436,
+ 'TT_MS_LANGID_GEORGIAN_GEORGIA' : 0x0437,
+ 'TT_MS_LANGID_FAEROESE_FAEROE_ISLANDS' : 0x0438,
+ 'TT_MS_LANGID_HINDI_INDIA' : 0x0439,
+ 'TT_MS_LANGID_MALTESE_MALTA' : 0x043a,
+ 'TT_MS_LANGID_SAMI_NORTHERN_NORWAY' : 0x043b,
+ 'TT_MS_LANGID_SAMI_NORTHERN_SWEDEN' : 0x083b,
+ 'TT_MS_LANGID_SAMI_NORTHERN_FINLAND' : 0x0C3b,
+ 'TT_MS_LANGID_SAMI_LULE_NORWAY' : 0x103b,
+ 'TT_MS_LANGID_SAMI_LULE_SWEDEN' : 0x143b,
+ 'TT_MS_LANGID_SAMI_SOUTHERN_NORWAY' : 0x183b,
+ 'TT_MS_LANGID_SAMI_SOUTHERN_SWEDEN' : 0x1C3b,
+ 'TT_MS_LANGID_SAMI_SKOLT_FINLAND' : 0x203b,
+ 'TT_MS_LANGID_SAMI_INARI_FINLAND' : 0x243b,
+ 'TT_MS_LANGID_SAAMI_LAPONIA' : 0x043b,
+ 'TT_MS_LANGID_SCOTTISH_GAELIC_UNITED_KINGDOM' : 0x083c,
+ 'TT_MS_LANGID_IRISH_GAELIC_IRELAND' : 0x043c,
+ 'TT_MS_LANGID_YIDDISH_GERMANY' : 0x043d,
+ 'TT_MS_LANGID_MALAY_MALAYSIA' : 0x043e,
+ 'TT_MS_LANGID_MALAY_BRUNEI_DARUSSALAM' : 0x083e,
+ 'TT_MS_LANGID_KAZAK_KAZAKSTAN' : 0x043f,
+ 'TT_MS_LANGID_KIRGHIZ_KIRGHIZSTAN' : 0x0440,
+ 'TT_MS_LANGID_KIRGHIZ_KIRGHIZ_REPUBLIC' : 0x0440,
+ 'TT_MS_LANGID_SWAHILI_KENYA' : 0x0441,
+ 'TT_MS_LANGID_TURKMEN_TURKMENISTAN' : 0x0442,
+ 'TT_MS_LANGID_UZBEK_UZBEKISTAN_LATIN' : 0x0443,
+ 'TT_MS_LANGID_UZBEK_UZBEKISTAN_CYRILLIC' : 0x0843,
+ 'TT_MS_LANGID_TATAR_TATARSTAN' : 0x0444,
+ 'TT_MS_LANGID_BENGALI_INDIA' : 0x0445,
+ 'TT_MS_LANGID_BENGALI_BANGLADESH' : 0x0845,
+ 'TT_MS_LANGID_PUNJABI_INDIA' : 0x0446,
+ 'TT_MS_LANGID_PUNJABI_ARABIC_PAKISTAN' : 0x0846,
+ 'TT_MS_LANGID_GUJARATI_INDIA' : 0x0447,
+ 'TT_MS_LANGID_ORIYA_INDIA' : 0x0448,
+ 'TT_MS_LANGID_TAMIL_INDIA' : 0x0449,
+ 'TT_MS_LANGID_TELUGU_INDIA' : 0x044a,
+ 'TT_MS_LANGID_KANNADA_INDIA' : 0x044b,
+ 'TT_MS_LANGID_MALAYALAM_INDIA' : 0x044c,
+ 'TT_MS_LANGID_ASSAMESE_INDIA' : 0x044d,
+ 'TT_MS_LANGID_MARATHI_INDIA' : 0x044e,
+ 'TT_MS_LANGID_SANSKRIT_INDIA' : 0x044f,
+ 'TT_MS_LANGID_MONGOLIAN_MONGOLIA' : 0x0450,
+ 'TT_MS_LANGID_MONGOLIAN_MONGOLIA_MONGOLIAN' : 0x0850,
+ 'TT_MS_LANGID_TIBETAN_CHINA' : 0x0451,
+ 'TT_MS_LANGID_DZONGHKA_BHUTAN' : 0x0851,
+ 'TT_MS_LANGID_TIBETAN_BHUTAN' : 0x0851,
+ 'TT_MS_LANGID_WELSH_WALES' : 0x0452,
+ 'TT_MS_LANGID_KHMER_CAMBODIA' : 0x0453,
+ 'TT_MS_LANGID_LAO_LAOS' : 0x0454,
+ 'TT_MS_LANGID_BURMESE_MYANMAR' : 0x0455,
+ 'TT_MS_LANGID_GALICIAN_SPAIN' : 0x0456,
+ 'TT_MS_LANGID_KONKANI_INDIA' : 0x0457,
+ 'TT_MS_LANGID_MANIPURI_INDIA' : 0x0458,
+ 'TT_MS_LANGID_SINDHI_INDIA' : 0x0459,
+ 'TT_MS_LANGID_SINDHI_PAKISTAN' : 0x0859,
+ 'TT_MS_LANGID_SYRIAC_SYRIA' : 0x045a,
+ 'TT_MS_LANGID_SINHALESE_SRI_LANKA' : 0x045b,
+ 'TT_MS_LANGID_CHEROKEE_UNITED_STATES' : 0x045c,
+ 'TT_MS_LANGID_INUKTITUT_CANADA' : 0x045d,
+ 'TT_MS_LANGID_AMHARIC_ETHIOPIA' : 0x045e,
+ 'TT_MS_LANGID_TAMAZIGHT_MOROCCO' : 0x045f,
+ 'TT_MS_LANGID_TAMAZIGHT_MOROCCO_LATIN' : 0x085f,
+ 'TT_MS_LANGID_KASHMIRI_PAKISTAN' : 0x0460,
+ 'TT_MS_LANGID_KASHMIRI_SASIA' : 0x0860,
+ 'TT_MS_LANGID_KASHMIRI_INDIA' : 0x0860,
+ 'TT_MS_LANGID_NEPALI_NEPAL' : 0x0461,
+ 'TT_MS_LANGID_NEPALI_INDIA' : 0x0861,
+ 'TT_MS_LANGID_FRISIAN_NETHERLANDS' : 0x0462,
+ 'TT_MS_LANGID_PASHTO_AFGHANISTAN' : 0x0463,
+ 'TT_MS_LANGID_FILIPINO_PHILIPPINES' : 0x0464,
+ 'TT_MS_LANGID_DHIVEHI_MALDIVES' : 0x0465,
+ 'TT_MS_LANGID_DIVEHI_MALDIVES' : 0x0465,
+ 'TT_MS_LANGID_EDO_NIGERIA' : 0x0466,
+ 'TT_MS_LANGID_FULFULDE_NIGERIA' : 0x0467,
+ 'TT_MS_LANGID_HAUSA_NIGERIA' : 0x0468,
+ 'TT_MS_LANGID_IBIBIO_NIGERIA' : 0x0469,
+ 'TT_MS_LANGID_YORUBA_NIGERIA' : 0x046a,
+ 'TT_MS_LANGID_QUECHUA_BOLIVIA' : 0x046b,
+ 'TT_MS_LANGID_QUECHUA_ECUADOR' : 0x086b,
+ 'TT_MS_LANGID_QUECHUA_PERU' : 0x0c6b,
+ 'TT_MS_LANGID_SEPEDI_SOUTH_AFRICA' : 0x046c,
+ 'TT_MS_LANGID_SOTHO_SOUTHERN_SOUTH_AFRICA' : 0x046c,
+ 'TT_MS_LANGID_IGBO_NIGERIA' : 0x0470,
+ 'TT_MS_LANGID_KANURI_NIGERIA' : 0x0471,
+ 'TT_MS_LANGID_OROMO_ETHIOPIA' : 0x0472,
+ 'TT_MS_LANGID_TIGRIGNA_ETHIOPIA' : 0x0473,
+ 'TT_MS_LANGID_TIGRIGNA_ERYTHREA' : 0x0873,
+ 'TT_MS_LANGID_TIGRIGNA_ERYTREA' : 0x0873,
+ 'TT_MS_LANGID_GUARANI_PARAGUAY' : 0x0474,
+ 'TT_MS_LANGID_HAWAIIAN_UNITED_STATES' : 0x0475,
+ 'TT_MS_LANGID_LATIN' : 0x0476,
+ 'TT_MS_LANGID_SOMALI_SOMALIA' : 0x0477,
+ 'TT_MS_LANGID_YI_CHINA' : 0x0478,
+ 'TT_MS_LANGID_PAPIAMENTU_NETHERLANDS_ANTILLES' : 0x0479,
+ 'TT_MS_LANGID_UIGHUR_CHINA' : 0x0480,
+ 'TT_MS_LANGID_MAORI_NEW_ZEALAND' : 0x0481 }
+globals().update(TT_MS_LANGIDS)
+
diff --git a/third_party/freetype-py/freetype/ft_enums/tt_name_ids.py b/third_party/freetype-py/freetype/ft_enums/tt_name_ids.py
new file mode 100644
index 0000000..c49a128
--- /dev/null
+++ b/third_party/freetype-py/freetype/ft_enums/tt_name_ids.py
@@ -0,0 +1,93 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# -----------------------------------------------------------------------------
+#
+# FreeType high-level python API - Copyright 2011-2012 Nicolas P. Rougier
+# Distributed under the terms of the new BSD license.
+#
+# -----------------------------------------------------------------------------
+
+"""
+Possible values of the 'name' identifier field in the name records of the TTF
+'name' table. These values are platform independent.
+
+TT_NAME_ID_COPYRIGHT
+
+TT_NAME_ID_FONT_FAMILY
+
+TT_NAME_ID_FONT_SUBFAMILY
+
+TT_NAME_ID_UNIQUE_ID
+
+TT_NAME_ID_FULL_NAME
+
+TT_NAME_ID_VERSION_STRING
+
+TT_NAME_ID_PS_NAME
+
+TT_NAME_ID_TRADEMARK
+
+TT_NAME_ID_MANUFACTURER
+
+TT_NAME_ID_DESIGNER
+
+TT_NAME_ID_DESCRIPTION
+
+TT_NAME_ID_VENDOR_URL
+
+TT_NAME_ID_DESIGNER_URL
+
+TT_NAME_ID_LICENSE
+
+TT_NAME_ID_LICENSE_URL
+
+TT_NAME_ID_PREFERRED_FAMILY
+
+TT_NAME_ID_PREFERRED_SUBFAMILY
+
+TT_NAME_ID_MAC_FULL_NAME
+
+TT_NAME_ID_SAMPLE_TEXT
+
+TT_NAME_ID_CID_FINDFONT_NAME
+
+TT_NAME_ID_WWS_FAMILY
+
+TT_NAME_ID_WWS_SUBFAMILY
+"""
+
+
+TT_NAME_IDS = {
+ 'TT_NAME_ID_COPYRIGHT' : 0,
+ 'TT_NAME_ID_FONT_FAMILY' : 1,
+ 'TT_NAME_ID_FONT_SUBFAMILY' : 2,
+ 'TT_NAME_ID_UNIQUE_ID' : 3,
+ 'TT_NAME_ID_FULL_NAME' : 4,
+ 'TT_NAME_ID_VERSION_STRING' : 5,
+ 'TT_NAME_ID_PS_NAME' : 6,
+ 'TT_NAME_ID_TRADEMARK' : 7,
+
+ # the following values are from the OpenType spec
+ 'TT_NAME_ID_MANUFACTURER' : 8,
+ 'TT_NAME_ID_DESIGNER' : 9,
+ 'TT_NAME_ID_DESCRIPTION' : 10,
+ 'TT_NAME_ID_VENDOR_URL' : 11,
+ 'TT_NAME_ID_DESIGNER_URL' : 12,
+ 'TT_NAME_ID_LICENSE' : 13,
+ 'TT_NAME_ID_LICENSE_URL' : 14,
+ # number 15 is reserved
+ 'TT_NAME_ID_PREFERRED_FAMILY' : 16,
+ 'TT_NAME_ID_PREFERRED_SUBFAMILY' : 17,
+ 'TT_NAME_ID_MAC_FULL_NAME' : 18,
+
+ # The following code is new as of 2000-01-21
+ 'TT_NAME_ID_SAMPLE_TEXT' : 19,
+
+ # This is new in OpenType 1.3
+ 'TT_NAME_ID_CID_FINDFONT_NAME' : 20,
+
+ # This is new in OpenType 1.5
+ 'TT_NAME_ID_WWS_FAMILY' : 21,
+ 'TT_NAME_ID_WWS_SUBFAMILY' : 22 }
+globals().update(TT_NAME_IDS)
+
diff --git a/third_party/freetype-py/freetype/ft_enums/tt_platforms.py b/third_party/freetype-py/freetype/ft_enums/tt_platforms.py
new file mode 100644
index 0000000..7b3c397
--- /dev/null
+++ b/third_party/freetype-py/freetype/ft_enums/tt_platforms.py
@@ -0,0 +1,63 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# -----------------------------------------------------------------------------
+#
+# FreeType high-level python API - Copyright 2011-2012 Nicolas P. Rougier
+# Distributed under the terms of the new BSD license.
+#
+# -----------------------------------------------------------------------------
+"""
+A list of valid values for the 'platform_id' identifier code in FT_CharMapRec
+and FT_SfntName structures.
+
+
+TT_PLATFORM_APPLE_UNICODE
+
+ Used by Apple to indicate a Unicode character map and/or name entry. See
+ TT_APPLE_ID_XXX for corresponding 'encoding_id' values. Note that name
+ entries in this format are coded as big-endian UCS-2 character codes only.
+
+
+TT_PLATFORM_MACINTOSH
+
+ Used by Apple to indicate a MacOS-specific charmap and/or name entry. See
+ TT_MAC_ID_XXX for corresponding 'encoding_id' values. Note that most TrueType
+ fonts contain an Apple roman charmap to be usable on MacOS systems (even if
+ they contain a Microsoft charmap as well).
+
+
+TT_PLATFORM_ISO
+
+ This value was used to specify ISO/IEC 10646 charmaps. It is however now
+ deprecated. See TT_ISO_ID_XXX for a list of corresponding 'encoding_id'
+ values.
+
+
+TT_PLATFORM_MICROSOFT
+
+ Used by Microsoft to indicate Windows-specific charmaps. See TT_MS_ID_XXX for
+ a list of corresponding 'encoding_id' values. Note that most fonts contain a
+ Unicode charmap using (TT_PLATFORM_MICROSOFT, TT_MS_ID_UNICODE_CS).
+
+
+TT_PLATFORM_CUSTOM
+
+ Used to indicate application-specific charmaps.
+
+
+TT_PLATFORM_ADOBE
+
+ This value isn't part of any font format specification, but is used by
+ FreeType to report Adobe-specific charmaps in an FT_CharMapRec structure. See
+ TT_ADOBE_ID_XXX.
+"""
+
+TT_PLATFORMS = {
+ 'TT_PLATFORM_APPLE_UNICODE' : 0,
+ 'TT_PLATFORM_MACINTOSH' : 1,
+ 'TT_PLATFORM_ISO' : 2, # deprecated
+ 'TT_PLATFORM_MICROSOFT' : 3,
+ 'TT_PLATFORM_CUSTOM' : 4,
+ 'TT_PLATFORM_ADOBE' : 7} # artificial
+globals().update(TT_PLATFORMS)
+
diff --git a/third_party/freetype-py/freetype/ft_errors.py b/third_party/freetype-py/freetype/ft_errors.py
new file mode 100644
index 0000000..04ccebc
--- /dev/null
+++ b/third_party/freetype-py/freetype/ft_errors.py
@@ -0,0 +1,105 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# -----------------------------------------------------------------------------
+#
+# FreeType high-level python API - Copyright 2011 Nicolas P. Rougier
+# Distributed under the terms of the new BSD license.
+#
+# -----------------------------------------------------------------------------
+'''
+Internal exception with freetype error message
+'''
+class FT_Exception(Exception):
+ def __init__(self, errcode, message=''):
+ self.message = message
+ self.errcode = errcode
+
+ def __str__(self):
+ return '%s: %s (%s)'%(self.__class__.__name__, self.message,
+ self._errors.get(self.errcode, 'unknown error'))
+
+ _errors = {
+ 0x00: "no error" ,
+ 0x01: "cannot open resource" ,
+ 0x02: "unknown file format" ,
+ 0x03: "broken file" ,
+ 0x04: "invalid FreeType version" ,
+ 0x05: "module version is too low" ,
+ 0x06: "invalid argument" ,
+ 0x07: "unimplemented feature" ,
+ 0x08: "broken table" ,
+ 0x09: "broken offset within table" ,
+ 0x10: "invalid glyph index" ,
+ 0x11: "invalid character code" ,
+ 0x12: "unsupported glyph image format" ,
+ 0x13: "cannot render this glyph format" ,
+ 0x14: "invalid outline" ,
+ 0x15: "invalid composite glyph" ,
+ 0x16: "too many hints" ,
+ 0x17: "invalid pixel size" ,
+ 0x20: "invalid object handle" ,
+ 0x21: "invalid library handle" ,
+ 0x22: "invalid module handle" ,
+ 0x23: "invalid face handle" ,
+ 0x24: "invalid size handle" ,
+ 0x25: "invalid glyph slot handle" ,
+ 0x26: "invalid charmap handle" ,
+ 0x27: "invalid cache manager handle" ,
+ 0x28: "invalid stream handle" ,
+ 0x30: "too many modules" ,
+ 0x31: "too many extensions" ,
+ 0x40: "out of memory" ,
+ 0x41: "unlisted object" ,
+ 0x51: "cannot open stream" ,
+ 0x52: "invalid stream seek" ,
+ 0x53: "invalid stream skip" ,
+ 0x54: "invalid stream read" ,
+ 0x55: "invalid stream operation" ,
+ 0x56: "invalid frame operation" ,
+ 0x57: "nested frame access" ,
+ 0x58: "invalid frame read" ,
+ 0x60: "raster uninitialized" ,
+ 0x61: "raster corrupted" ,
+ 0x62: "raster overflow" ,
+ 0x63: "negative height while rastering" ,
+ 0x70: "too many registered caches" ,
+ 0x80: "invalid opcode" ,
+ 0x81: "too few arguments" ,
+ 0x82: "stack overflow" ,
+ 0x83: "code overflow" ,
+ 0x84: "bad argument" ,
+ 0x85: "division by zero" ,
+ 0x86: "invalid reference" ,
+ 0x87: "found debug opcode" ,
+ 0x88: "found ENDF opcode in execution stream" ,
+ 0x89: "nested DEFS" ,
+ 0x8A: "invalid code range" ,
+ 0x8B: "execution context too long" ,
+ 0x8C: "too many function definitions" ,
+ 0x8D: "too many instruction definitions" ,
+ 0x8E: "SFNT font table missing" ,
+ 0x8F: "horizontal header (hhea, table missing" ,
+ 0x90: "locations (loca, table missing" ,
+ 0x91: "name table missing" ,
+ 0x92: "character map (cmap, table missing" ,
+ 0x93: "horizontal metrics (hmtx, table missing" ,
+ 0x94: "PostScript (post, table missing" ,
+ 0x95: "invalid horizontal metrics" ,
+ 0x96: "invalid character map (cmap, format" ,
+ 0x97: "invalid ppem value" ,
+ 0x98: "invalid vertical metrics" ,
+ 0x99: "could not find context" ,
+ 0x9A: "invalid PostScript (post, table format" ,
+ 0x9B: "invalid PostScript (post, table" ,
+ 0xA0: "opcode syntax error" ,
+ 0xA1: "argument stack underflow" ,
+ 0xA2: "ignore" ,
+ 0xB0: "`STARTFONT' field missing" ,
+ 0xB1: "`FONT' field missing" ,
+ 0xB2: "`SIZE' field missing" ,
+ 0xB3: "`CHARS' field missing" ,
+ 0xB4: "`STARTCHAR' field missing" ,
+ 0xB5: "`ENCODING' field missing" ,
+ 0xB6: "`BBX' field missing" ,
+ 0xB7: "`BBX' too big" ,
+ }
diff --git a/third_party/freetype-py/freetype/ft_structs.py b/third_party/freetype-py/freetype/ft_structs.py
new file mode 100644
index 0000000..c669c92
--- /dev/null
+++ b/third_party/freetype-py/freetype/ft_structs.py
@@ -0,0 +1,944 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# -----------------------------------------------------------------------------
+#
+# FreeType high-level python API - Copyright 2011 Nicolas P. Rougier
+# Distributed under the terms of the new BSD license.
+#
+# -----------------------------------------------------------------------------
+'''
+Freetype structured types
+-------------------------
+
+FT_Library: A handle to a FreeType library instance.
+
+FT_Vector: A simple structure used to store a 2D vector.
+
+FT_BBox: A structure used to hold an outline's bounding box.
+
+FT_Matrix: A simple structure used to store a 2x2 matrix.
+
+FT_UnitVector: A simple structure used to store a 2D vector unit vector.
+
+FT_Bitmap: A structure used to describe a bitmap or pixmap to the raster.
+
+FT_Data: Read-only binary data represented as a pointer and a length.
+
+FT_Generic: Client applications generic data.
+
+FT_Bitmap_Size: Metrics of a bitmap strike.
+
+FT_Charmap: The base charmap structure.
+
+FT_Glyph_Metrics:A structure used to model the metrics of a single glyph.
+
+FT_Outline: This structure is used to describe an outline to the scan-line
+ converter.
+
+FT_GlyphSlot: FreeType root glyph slot class structure.
+
+FT_Glyph: The root glyph structure contains a given glyph image plus its
+ advance width in 16.16 fixed float format.
+
+FT_Size_Metrics: The size metrics structure gives the metrics of a size object.
+
+FT_Size: FreeType root size class structure.
+
+FT_Face: FreeType root face class structure.
+
+FT_Parameter: A simple structure used to pass more or less generic parameters
+ to FT_Open_Face.
+
+FT_Open_Args: A structure used to indicate how to open a new font file or
+ stream.
+
+FT_SfntName: A structure used to model an SFNT 'name' table entry.
+
+FT_Stroker: Opaque handler to a path stroker object.
+
+FT_BitmapGlyph: A structure used for bitmap glyph images.
+'''
+from freetype.ft_types import *
+
+
+# -----------------------------------------------------------------------------
+# A handle to a FreeType library instance. Each 'library' is completely
+# independent from the others; it is the 'root' of a set of objects like fonts,
+# faces, sizes, etc.
+class FT_LibraryRec(Structure):
+ '''
+ A handle to a FreeType library instance. Each 'library' is completely
+ independent from the others; it is the 'root' of a set of objects like
+ fonts, faces, sizes, etc.
+ '''
+ _fields_ = [ ]
+FT_Library = POINTER(FT_LibraryRec)
+
+
+
+# -----------------------------------------------------------------------------
+# A simple structure used to store a 2D vector; coordinates are of the FT_Pos
+# type.
+class FT_Vector(Structure):
+ '''
+ A simple structure used to store a 2D vector; coordinates are of the FT_Pos
+ type.
+
+ x: The horizontal coordinate.
+ y: The vertical coordinate.
+ '''
+ _fields_ = [('x', FT_Pos),
+ ('y', FT_Pos)]
+
+
+
+# -----------------------------------------------------------------------------
+# A structure used to hold an outline's bounding box, i.e., the coordinates of
+# its extrema in the horizontal and vertical directions.
+#
+# The bounding box is specified with the coordinates of the lower left and the
+# upper right corner. In PostScript, those values are often called (llx,lly)
+# and (urx,ury), respectively.
+#
+# If 'yMin' is negative, this value gives the glyph's descender. Otherwise, the
+# glyph doesn't descend below the baseline. Similarly, if 'ymax' is positive,
+# this value gives the glyph's ascender.
+#
+# 'xMin' gives the horizontal distance from the glyph's origin to the left edge
+# of the glyph's bounding box. If 'xMin' is negative, the glyph extends to the
+# left of the origin.
+class FT_BBox(Structure):
+ '''
+ A structure used to hold an outline's bounding box, i.e., the coordinates
+ of its extrema in the horizontal and vertical directions.
+
+ The bounding box is specified with the coordinates of the lower left and
+ the upper right corner. In PostScript, those values are often called
+ (llx,lly) and (urx,ury), respectively.
+
+ If 'yMin' is negative, this value gives the glyph's descender. Otherwise,
+ the glyph doesn't descend below the baseline. Similarly, if 'ymax' is
+ positive, this value gives the glyph's ascender.
+
+ 'xMin' gives the horizontal distance from the glyph's origin to the left
+ edge of the glyph's bounding box. If 'xMin' is negative, the glyph extends
+ to the left of the origin.
+
+ xMin: The horizontal minimum (left-most).
+ yMin: The vertical minimum (bottom-most).
+ xMax: The horizontal maximum (right-most).
+ yMax: The vertical maximum (top-most).
+ '''
+ _fields_ = [('xMin', FT_Pos),
+ ('yMin', FT_Pos),
+ ('xMax', FT_Pos),
+ ('yMax', FT_Pos)]
+
+
+
+# -----------------------------------------------------------------------------
+# A simple structure used to store a 2x2 matrix. Coefficients are in 16.16
+# fixed float format. The computation performed is:
+# x' = x*xx + y*xy
+# y' = x*yx + y*yy
+class FT_Matrix(Structure):
+ '''
+ A simple structure used to store a 2x2 matrix. Coefficients are in 16.16
+ fixed float format. The computation performed is:
+
+ x' = x*xx + y*xy
+ y' = x*yx + y*yy
+
+ xx: Matrix coefficient.
+ xy: Matrix coefficient.
+ yx: Matrix coefficient.
+ yy: Matrix coefficient.
+ '''
+ _fields_ = [('xx', FT_Fixed),
+ ('xy', FT_Fixed),
+ ('yx', FT_Fixed),
+ ('yy', FT_Fixed)]
+
+
+
+# -----------------------------------------------------------------------------
+# A simple structure used to store a 2D vector unit vector. Uses FT_F2Dot14
+# types.
+class FT_UnitVector(Structure):
+ '''
+ A simple structure used to store a 2D vector unit vector. Uses FT_F2Dot14
+ types.
+
+ x: The horizontal coordinate.
+ y: The vertical coordinate.
+ '''
+ _fields_ = [('x', FT_F2Dot14),
+ ('y', FT_F2Dot14)]
+
+
+
+# -----------------------------------------------------------------------------
+# A structure used to describe a bitmap or pixmap to the raster. Note that we
+# now manage pixmaps of various depths through the 'pixel_mode' field.
+class FT_Bitmap(Structure):
+ '''
+ A structure used to describe a bitmap or pixmap to the raster. Note that we
+ now manage pixmaps of various depths through the 'pixel_mode' field.
+
+ rows: The number of bitmap rows.
+
+ width: The number of pixels in bitmap row.
+
+ pitch: The pitch's absolute value is the number of bytes taken by one
+ bitmap row, including padding. However, the pitch is positive when
+ the bitmap has a 'down' flow, and negative when it has an 'up'
+ flow. In all cases, the pitch is an offset to add to a bitmap
+ pointer in order to go down one row.
+
+ Note that 'padding' means the alignment of a bitmap to a byte
+ border, and FreeType functions normally align to the smallest
+ possible integer value.
+
+ For the B/W rasterizer, 'pitch' is always an even number.
+
+ To change the pitch of a bitmap (say, to make it a multiple of 4),
+ use FT_Bitmap_Convert. Alternatively, you might use callback
+ functions to directly render to the application's surface; see the
+ file 'example2.py' in the tutorial for a demonstration.
+
+ buffer: A typeless pointer to the bitmap buffer. This value should be
+ aligned on 32-bit boundaries in most cases.
+
+ num_grays: This field is only used with FT_PIXEL_MODE_GRAY; it gives the
+ number of gray levels used in the bitmap.
+
+ pixel_mode: The pixel mode, i.e., how pixel bits are stored. See
+ FT_Pixel_Mode for possible values.
+
+ palette_mode: This field is intended for paletted pixel modes; it indicates
+ how the palette is stored. Not used currently.
+
+ palette: A typeless pointer to the bitmap palette; this field is intended
+ for paletted pixel modes. Not used currently.
+ '''
+ _fields_ = [
+ ('rows', c_int),
+ ('width', c_int),
+ ('pitch', c_int),
+ # declaring buffer as c_char_p confuses ctypes
+ ('buffer', POINTER(c_ubyte)),
+ ('num_grays', c_short),
+ ('pixel_mode', c_ubyte),
+ ('palette_mode', c_char),
+ ('palette', c_void_p) ]
+
+
+
+# -----------------------------------------------------------------------------
+# Read-only binary data represented as a pointer and a length.
+class FT_Data(Structure):
+ '''
+ Read-only binary data represented as a pointer and a length.
+
+ pointer: The data.
+ length: The length of the data in bytes.
+ '''
+ _fields_ = [('pointer', POINTER(FT_Byte)),
+ ('y', FT_Int)]
+
+
+
+# -----------------------------------------------------------------------------
+# Client applications often need to associate their own data to a variety of
+# FreeType core objects. For example, a text layout API might want to associate
+# a glyph cache to a given size object.
+#
+# Most FreeType object contains a 'generic' field, of type FT_Generic, which
+# usage is left to client applications and font servers.
+#
+# It can be used to store a pointer to client-specific data, as well as the
+# address of a 'finalizer' function, which will be called by FreeType when the
+# object is destroyed (for example, the previous client example would put the
+# address of the glyph cache destructor in the 'finalizer' field).
+class FT_Generic(Structure):
+ '''
+ Client applications often need to associate their own data to a variety of
+ FreeType core objects. For example, a text layout API might want to
+ associate a glyph cache to a given size object.
+
+ Most FreeType object contains a 'generic' field, of type FT_Generic, which
+ usage is left to client applications and font servers.
+
+ It can be used to store a pointer to client-specific data, as well as the
+ address of a 'finalizer' function, which will be called by FreeType when
+ the object is destroyed (for example, the previous client example would put
+ the address of the glyph cache destructor in the 'finalizer' field).
+
+ data: A typeless pointer to any client-specified data. This field is
+ completely ignored by the FreeType library.
+ finalizer: A pointer to a 'generic finalizer' function, which will be
+ called when the object is destroyed. If this field is set to
+ NULL, no code will be called.
+ '''
+ _fields_ = [('data', c_void_p),
+ ('finalizer', FT_Generic_Finalizer)]
+
+
+
+
+# -----------------------------------------------------------------------------
+# This structure models the metrics of a bitmap strike (i.e., a set of glyphs
+# for a given point size and resolution) in a bitmap font. It is used for the
+# 'available_sizes' field of FT_Face.
+class FT_Bitmap_Size(Structure):
+ '''
+ This structure models the metrics of a bitmap strike (i.e., a set of glyphs
+ for a given point size and resolution) in a bitmap font. It is used for the
+ 'available_sizes' field of FT_Face.
+
+ height: The vertical distance, in pixels, between two consecutive
+ baselines. It is always positive.
+
+ width: The average width, in pixels, of all glyphs in the strike.
+
+ size: The nominal size of the strike in 26.6 fractional points. This field
+ is not very useful.
+
+ x_ppem: The horizontal ppem (nominal width) in 26.6 fractional pixels.
+
+ y_ppem: The vertical ppem (nominal height) in 26.6 fractional pixels.
+ '''
+ _fields_ = [
+ ('height', FT_Short),
+ ('width', FT_Short),
+ ('size', FT_Pos),
+ ('x_ppem', FT_Pos),
+ ('y_ppem', FT_Pos) ]
+
+
+
+# -----------------------------------------------------------------------------
+# The base charmap structure.
+class FT_CharmapRec(Structure):
+ '''
+ The base charmap structure.
+
+ face : A handle to the parent face object.
+
+ encoding : An FT_Encoding tag identifying the charmap. Use this with
+ FT_Select_Charmap.
+
+ platform_id: An ID number describing the platform for the following
+ encoding ID. This comes directly from the TrueType
+ specification and should be emulated for other formats.
+
+ encoding_id: A platform specific encoding number. This also comes from the
+ TrueType specification and should be emulated similarly.
+ '''
+ _fields_ = [
+ ('face', c_void_p), # Shoudl be FT_Face
+ ('encoding', FT_Encoding),
+ ('platform_id', FT_UShort),
+ ('encoding_id', FT_UShort),
+ ]
+FT_Charmap = POINTER(FT_CharmapRec)
+
+
+
+# -----------------------------------------------------------------------------
+# A structure used to model the metrics of a single glyph. The values are
+# expressed in 26.6 fractional pixel format; if the flag FT_LOAD_NO_SCALE has
+# been used while loading the glyph, values are expressed in font units
+# instead.
+class FT_Glyph_Metrics(Structure):
+ '''
+ A structure used to model the metrics of a single glyph. The values are
+ expressed in 26.6 fractional pixel format; if the flag FT_LOAD_NO_SCALE has
+ been used while loading the glyph, values are expressed in font units
+ instead.
+
+ width: The glyph's width.
+
+ height: The glyph's height.
+
+ horiBearingX: Left side bearing for horizontal layout.
+
+ horiBearingY: Top side bearing for horizontal layout.
+
+ horiAdvance: Advance width for horizontal layout.
+
+ vertBearingX: Left side bearing for vertical layout.
+
+ vertBearingY: Top side bearing for vertical layout.
+
+ vertAdvance: Advance height for vertical layout.
+ '''
+ _fields_ = [
+ ('width', FT_Pos),
+ ('height', FT_Pos),
+ ('horiBearingX', FT_Pos),
+ ('horiBearingY', FT_Pos),
+ ('horiAdvance', FT_Pos),
+ ('vertBearingX', FT_Pos),
+ ('vertBearingY', FT_Pos),
+ ('vertAdvance', FT_Pos),
+ ]
+
+
+
+# -----------------------------------------------------------------------------
+# This structure is used to describe an outline to the scan-line converter.
+class FT_Outline(Structure):
+ '''
+ This structure is used to describe an outline to the scan-line converter.
+
+ n_contours: The number of contours in the outline.
+
+ n_points: The number of points in the outline.
+
+ points: A pointer to an array of 'n_points' FT_Vector elements, giving the
+ outline's point coordinates.
+
+ tags: A pointer to an array of 'n_points' chars, giving each outline
+ point's type.
+
+ If bit 0 is unset, the point is 'off' the curve, i.e., a Bezier
+ control point, while it is 'on' if set.
+
+ Bit 1 is meaningful for 'off' points only. If set, it indicates a
+ third-order Bezier arc control point; and a second-order control
+ point if unset.
+
+ If bit 2 is set, bits 5-7 contain the drop-out mode (as defined in
+ the OpenType specification; the value is the same as the argument to
+ the SCANMODE instruction).
+
+ Bits 3 and 4 are reserved for internal purposes.
+
+ contours: An array of 'n_contours' shorts, giving the end point of each
+ contour within the outline. For example, the first contour is
+ defined by the points '0' to 'contours[0]', the second one is
+ defined by the points 'contours[0]+1' to 'contours[1]', etc.
+
+ flags: A set of bit flags used to characterize the outline and give hints
+ to the scan-converter and hinter on how to convert/grid-fit it. See
+ FT_OUTLINE_FLAGS.
+ '''
+ _fields_ = [
+ ('n_contours', c_short),
+ ('n_points', c_short),
+ ('points', POINTER(FT_Vector)),
+ # declaring buffer as c_char_p would prevent us to acces all tags
+ ('tags', POINTER(c_ubyte)),
+ ('contours', POINTER(c_short)),
+ ('flags', c_int),
+ ]
+
+
+# -----------------------------------------------------------------------------
+# The root glyph structure contains a given glyph image plus its advance width
+# in 16.16 fixed float format.
+
+class FT_GlyphRec(Structure):
+ '''
+ The root glyph structure contains a given glyph image plus its advance
+ width in 16.16 fixed float format.
+
+ library: A handle to the FreeType library object.
+
+ clazz: A pointer to the glyph's class. Private.
+
+ format: The format of the glyph's image.
+
+ advance: A 16.16 vector that gives the glyph's advance width.
+ '''
+ _fields_ = [
+ ('library', FT_Library),
+ ('clazz', c_void_p),
+ ('format', FT_Glyph_Format),
+ ('advance', FT_Vector)
+ ]
+FT_Glyph = POINTER(FT_GlyphRec)
+
+
+
+# -----------------------------------------------------------------------------
+# FreeType root glyph slot class structure. A glyph slot is a container where
+# individual glyphs can be loaded, be they in outline or bitmap format.
+class FT_GlyphSlotRec(Structure):
+ '''
+ FreeType root glyph slot class structure. A glyph slot is a container where
+ individual glyphs can be loaded, be they in outline or bitmap format.
+
+ library: A handle to the FreeType library instance this slot belongs to.
+
+ face: A handle to the parent face object.
+
+ next: In some cases (like some font tools), several glyph slots per face
+ object can be a good thing. As this is rare, the glyph slots are
+ listed through a direct, single-linked list using its 'next' field.
+
+ generic: A typeless pointer which is unused by the FreeType library or any
+ of its drivers. It can be used by client applications to link
+ their own data to each glyph slot object.
+
+ metrics: The metrics of the last loaded glyph in the slot. The returned
+ values depend on the last load flags (see the FT_Load_Glyph API
+ function) and can be expressed either in 26.6 fractional pixels or
+ font units.
+
+ Note that even when the glyph image is transformed, the metrics
+ are not.
+
+ linearHoriAdvance: The advance width of the unhinted glyph. Its value is
+ expressed in 16.16 fractional pixels, unless
+ FT_LOAD_LINEAR_DESIGN is set when loading the
+ glyph. This field can be important to perform correct
+ WYSIWYG layout. Only relevant for outline glyphs.
+
+ linearVertAdvance: The advance height of the unhinted glyph. Its value is
+ expressed in 16.16 fractional pixels, unless
+ FT_LOAD_LINEAR_DESIGN is set when loading the
+ glyph. This field can be important to perform correct
+ WYSIWYG layout. Only relevant for outline glyphs.
+
+ advance: This shorthand is, depending on FT_LOAD_IGNORE_TRANSFORM, the
+ transformed advance width for the glyph (in 26.6 fractional pixel
+ format). As specified with FT_LOAD_VERTICAL_LAYOUT, it uses either
+ the 'horiAdvance' or the 'vertAdvance' value of 'metrics' field.
+
+ format: This field indicates the format of the image contained in the glyph
+ slot. Typically FT_GLYPH_FORMAT_BITMAP, FT_GLYPH_FORMAT_OUTLINE, or
+ FT_GLYPH_FORMAT_COMPOSITE, but others are possible.
+
+ bitmap: This field is used as a bitmap descriptor when the slot format is
+ FT_GLYPH_FORMAT_BITMAP. Note that the address and content of the
+ bitmap buffer can change between calls of FT_Load_Glyph and a few
+ other functions.
+
+ bitmap_left: This is the bitmap's left bearing expressed in integer
+ pixels. Of course, this is only valid if the format is
+ FT_GLYPH_FORMAT_BITMAP.
+
+ bitmap_top: This is the bitmap's top bearing expressed in integer
+ pixels. Remember that this is the distance from the baseline to
+ the top-most glyph scanline, upwards y coordinates being
+ positive.
+
+ outline: The outline descriptor for the current glyph image if its format
+ is FT_GLYPH_FORMAT_OUTLINE. Once a glyph is loaded, 'outline' can
+ be transformed, distorted, embolded, etc. However, it must not be
+ freed.
+
+ num_subglyphs: The number of subglyphs in a composite glyph. This field is
+ only valid for the composite glyph format that should
+ normally only be loaded with the FT_LOAD_NO_RECURSE
+ flag. For now this is internal to FreeType.
+
+ subglyphs: An array of subglyph descriptors for composite glyphs. There are
+ 'num_subglyphs' elements in there. Currently internal to
+ FreeType.
+
+ control_data: Certain font drivers can also return the control data for a
+ given glyph image (e.g. TrueType bytecode, Type 1
+ charstrings, etc.). This field is a pointer to such data.
+
+ control_len: This is the length in bytes of the control data.
+
+ other: Really wicked formats can use this pointer to present their own
+ glyph image to client applications. Note that the application needs
+ to know about the image format.
+
+ lsb_delta: The difference between hinted and unhinted left side bearing
+ while autohinting is active. Zero otherwise.
+
+ rsb_delta: The difference between hinted and unhinted right side bearing
+ while autohinting is active. Zero otherwise.
+ '''
+ _fields_ = [
+ ('library', FT_Library),
+ ('face', c_void_p),
+ ('next', c_void_p),
+ ('reserved', c_uint),
+ ('generic', FT_Generic),
+
+ ('metrics', FT_Glyph_Metrics),
+ ('linearHoriAdvance', FT_Fixed),
+ ('linearVertAdvance', FT_Fixed),
+ ('advance', FT_Vector),
+
+ ('format', FT_Glyph_Format),
+
+ ('bitmap', FT_Bitmap),
+ ('bitmap_left', FT_Int),
+ ('bitmap_top', FT_Int),
+
+ ('outline', FT_Outline),
+ ('num_subglyphs', FT_UInt),
+ ('subglyphs', c_void_p),
+
+ ('control_data', c_void_p),
+ ('control_len', c_long),
+
+ ('lsb_delta', FT_Pos),
+ ('rsb_delta', FT_Pos),
+ ('other', c_void_p),
+ ('internal', c_void_p),
+ ]
+FT_GlyphSlot = POINTER(FT_GlyphSlotRec)
+
+
+
+# -----------------------------------------------------------------------------
+# The size metrics structure gives the metrics of a size object.
+class FT_Size_Metrics(Structure):
+ '''
+ The size metrics structure gives the metrics of a size object.
+
+ x_ppem: The width of the scaled EM square in pixels, hence the term 'ppem'
+ (pixels per EM). It is also referred to as 'nominal width'.
+
+ y_ppem: The height of the scaled EM square in pixels, hence the term 'ppem'
+ (pixels per EM). It is also referred to as 'nominal height'.
+
+ x_scale: A 16.16 fractional scaling value used to convert horizontal
+ metrics from font units to 26.6 fractional pixels. Only relevant
+ for scalable font formats.
+
+ y_scale: A 16.16 fractional scaling value used to convert vertical metrics
+ from font units to 26.6 fractional pixels. Only relevant for
+ scalable font formats.
+
+ ascender: The ascender in 26.6 fractional pixels. See FT_FaceRec for the
+ details.
+
+ descender: The descender in 26.6 fractional pixels. See FT_FaceRec for the
+ details.
+
+ height: The height in 26.6 fractional pixels. See FT_FaceRec for the
+ details.
+
+ max_advance: The maximal advance width in 26.6 fractional pixels. See
+ FT_FaceRec for the details.
+ '''
+ _fields_ = [
+ ('x_ppem', FT_UShort),
+ ('y_ppem', FT_UShort),
+
+ ('x_scale', FT_Fixed),
+ ('y_scale', FT_Fixed),
+
+ ('ascender', FT_Pos),
+ ('descender', FT_Pos),
+ ('height', FT_Pos),
+ ('max_advance', FT_Pos),
+ ]
+
+
+
+# -----------------------------------------------------------------------------
+# FreeType root size class structure. A size object models a face object at a
+# given size.
+class FT_SizeRec(Structure):
+ '''
+ FreeType root size class structure. A size object models a face object at a
+ given size.
+
+ face: Handle to the parent face object.
+
+ generic: A typeless pointer, which is unused by the FreeType library or any
+ of its drivers. It can be used by client applications to link
+ their own data to each size object.
+
+ metrics: Metrics for this size object. This field is read-only.
+ '''
+ _fields_ = [
+ ('face', c_void_p),
+ ('generic', FT_Generic),
+ ('metrics', FT_Size_Metrics),
+ ('internal', c_void_p),
+ ]
+FT_Size = POINTER(FT_SizeRec)
+
+
+
+# -----------------------------------------------------------------------------
+# FreeType root face class structure. A face object models a typeface in a font
+# file.
+class FT_FaceRec(Structure):
+ '''
+ FreeType root face class structure. A face object models a typeface in a
+ font file.
+
+ num_faces: The number of faces in the font file. Some font formats can have
+ multiple faces in a font file.
+
+ face_index: The index of the face in the font file. It is set to 0 if there
+ is only one face in the font file.
+
+ face_flags: A set of bit flags that give important information about the
+ face; see FT_FACE_FLAG_XXX for the details.
+
+ style_flags: A set of bit flags indicating the style of the face; see
+ FT_STYLE_FLAG_XXX for the details.
+
+ num_glyphs: The number of glyphs in the face. If the face is scalable and
+ has sbits (see 'num_fixed_sizes'), it is set to the number of
+ outline glyphs.
+
+ For CID-keyed fonts, this value gives the highest CID used in
+ the font.
+
+ family_name: The face's family name. This is an ASCII string, usually in
+ English, which describes the typeface's family (like 'Times
+ New Roman', 'Bodoni', 'Garamond', etc). This is a least common
+ denominator used to list fonts. Some formats (TrueType &
+ OpenType) provide localized and Unicode versions of this
+ string. Applications should use the format specific interface
+ to access them. Can be NULL (e.g., in fonts embedded in a PDF
+ file).
+
+ style_name: The face's style name. This is an ASCII string, usually in
+ English, which describes the typeface's style (like 'Italic',
+ 'Bold', 'Condensed', etc). Not all font formats provide a style
+ name, so this field is optional, and can be set to NULL. As for
+ 'family_name', some formats provide localized and Unicode
+ versions of this string. Applications should use the format
+ specific interface to access them.
+
+ num_fixed_sizes: The number of bitmap strikes in the face. Even if the face
+ is scalable, there might still be bitmap strikes, which
+ are called 'sbits' in that case.
+
+ available_sizes: An array of FT_Bitmap_Size for all bitmap strikes in the
+ face. It is set to NULL if there is no bitmap strike.
+
+ num_charmaps: The number of charmaps in the face.
+
+ charmaps: An array of the charmaps of the face.
+
+ generic: A field reserved for client uses. See the FT_Generic type
+ description.
+
+ bbox: The font bounding box. Coordinates are expressed in font units (see
+ 'units_per_EM'). The box is large enough to contain any glyph from
+ the font. Thus, 'bbox.yMax' can be seen as the 'maximal ascender',
+ and 'bbox.yMin' as the 'minimal descender'. Only relevant for
+ scalable formats.
+
+ Note that the bounding box might be off by (at least) one pixel for
+ hinted fonts. See FT_Size_Metrics for further discussion.
+
+ units_per_EM: The number of font units per EM square for this face. This is
+ typically 2048 for TrueType fonts, and 1000 for Type 1
+ fonts. Only relevant for scalable formats.
+
+ ascender: The typographic ascender of the face, expressed in font
+ units. For font formats not having this information, it is set to
+ 'bbox.yMax'. Only relevant for scalable formats.
+
+ descender: The typographic descender of the face, expressed in font
+ units. For font formats not having this information, it is set
+ to 'bbox.yMin'. Note that this field is usually negative. Only
+ relevant for scalable formats.
+
+ height: The height is the vertical distance between two consecutive
+ baselines, expressed in font units. It is always positive. Only
+ relevant for scalable formats.
+
+ max_advance_width: The maximal advance width, in font units, for all glyphs
+ in this face. This can be used to make word wrapping
+ computations faster. Only relevant for scalable formats.
+
+ max_advance_height: The maximal advance height, in font units, for all
+ glyphs in this face. This is only relevant for vertical
+ layouts, and is set to 'height' for fonts that do not
+ provide vertical metrics. Only relevant for scalable
+ formats.
+
+ underline_position: The position, in font units, of the underline line for
+ this face. It is the center of the underlining
+ stem. Only relevant for scalable formats.
+
+ underline_thickness: The thickness, in font units, of the underline for
+ this face. Only relevant for scalable formats.
+
+ glyph: The face's associated glyph slot(s).
+
+ size: The current active size for this face.
+
+ charmap: The current active charmap for this face.
+ '''
+ _fields_ = [
+ ('num_faces', FT_Long),
+ ('face_index', FT_Long),
+
+ ('face_flags', FT_Long),
+ ('style_flags', FT_Long),
+
+ ('num_glyphs', FT_Long),
+
+ ('family_name', FT_String_p),
+ ('style_name', FT_String_p),
+
+ ('num_fixed_sizes', FT_Int),
+ ('available_sizes', POINTER(FT_Bitmap_Size)),
+
+ ('num_charmaps', c_int),
+ ('charmaps', POINTER(FT_Charmap)),
+
+ ('generic', FT_Generic),
+
+ # The following member variables (down to `underline_thickness')
+ # are only relevant to scalable outlines; cf. @FT_Bitmap_Size
+ # for bitmap fonts.
+ ('bbox', FT_BBox),
+
+ ('units_per_EM', FT_UShort),
+ ('ascender', FT_Short),
+ ('descender', FT_Short),
+ ('height', FT_Short),
+
+ ('max_advance_width', FT_Short),
+ ('max_advance_height', FT_Short),
+
+ ('underline_position', FT_Short),
+ ('underline_thickness', FT_Short),
+
+ ('glyph', FT_GlyphSlot),
+ ('size', FT_Size),
+ ('charmap', FT_Charmap),
+
+ # private
+ ('driver', c_void_p),
+ ('memory', c_void_p),
+ ('stream', c_void_p),
+ ('sizes_list_head', c_void_p),
+ ('sizes_list_tail', c_void_p),
+ ('autohint', FT_Generic),
+ ('extensions', c_void_p),
+ ('internal', c_void_p),
+ ]
+FT_Face = POINTER(FT_FaceRec)
+
+
+
+# -----------------------------------------------------------------------------
+# A simple structure used to pass more or less generic parameters to
+# FT_Open_Face.
+class FT_Parameter(Structure):
+ '''
+ A simple structure used to pass more or less generic parameters to
+ FT_Open_Face.
+
+ tag: A four-byte identification tag.
+
+ data: A pointer to the parameter data
+ '''
+ _fields_ = [
+ ('tag', FT_ULong),
+ ('data', FT_Pointer) ]
+FT_Parameter_p = POINTER(FT_Parameter)
+
+
+
+# -----------------------------------------------------------------------------
+# A structure used to indicate how to open a new font file or stream. A pointer
+# to such a structure can be used as a parameter for the functions FT_Open_Face
+# and FT_Attach_Stream.
+class FT_Open_Args(Structure):
+ '''
+ A structure used to indicate how to open a new font file or stream. A pointer
+ to such a structure can be used as a parameter for the functions FT_Open_Face
+ and FT_Attach_Stream.
+
+ flags: A set of bit flags indicating how to use the structure.
+
+ memory_base: The first byte of the file in memory.
+
+ memory_size: The size in bytes of the file in memory.
+
+ pathname: A pointer to an 8-bit file pathname.
+
+ stream: A handle to a source stream object.
+
+ driver: This field is exclusively used by FT_Open_Face; it simply specifies
+ the font driver to use to open the face. If set to 0, FreeType
+ tries to load the face with each one of the drivers in its list.
+
+ num_params: The number of extra parameters.
+
+ params: Extra parameters passed to the font driver when opening a new face.
+ '''
+ _fields_ = [
+ ('flags', FT_UInt),
+ ('memory_base', POINTER(FT_Byte)),
+ ('memory_size', FT_Long),
+ ('pathname', FT_String_p),
+ ('stream', c_void_p),
+ ('driver', c_void_p),
+ ('num_params', FT_Int),
+ ('params', FT_Parameter_p) ]
+
+
+
+# -----------------------------------------------------------------------------
+# A structure used to model an SFNT 'name' table entry.
+
+class FT_SfntName(Structure):
+ '''
+ platform_id: The platform ID for 'string'.
+
+ encoding_id: The encoding ID for 'string'.
+
+ language_id: The language ID for 'string'
+
+ name_id: An identifier for 'string'
+
+ string: The 'name' string. Note that its format differs depending on the
+ (platform,encoding) pair. It can be a Pascal String, a UTF-16 one,
+ etc.
+
+ Generally speaking, the string is not zero-terminated. Please refer
+ to the TrueType specification for details.
+
+ string_len: The length of 'string' in bytes.
+ '''
+
+ _fields_ = [
+ ('platform_id', FT_UShort),
+ ('encoding_id', FT_UShort),
+ ('language_id', FT_UShort),
+ ('name_id', FT_UShort),
+ # this string is *not* null-terminated!
+ ('string', POINTER(FT_Byte)),
+ ('string_len', FT_UInt) ]
+
+
+
+# -----------------------------------------------------------------------------
+# Opaque handler to a path stroker object.
+class FT_StrokerRec(Structure):
+ '''
+ Opaque handler to a path stroker object.
+ '''
+ _fields_ = [ ]
+FT_Stroker = POINTER(FT_StrokerRec)
+
+
+# -----------------------------------------------------------------------------
+# A structure used for bitmap glyph images. This really is a 'sub-class' of
+# FT_GlyphRec.
+#
+class FT_BitmapGlyphRec(Structure):
+ '''
+ A structure used for bitmap glyph images. This really is a 'sub-class' of
+ FT_GlyphRec.
+ '''
+ _fields_ = [
+ ('root' , FT_GlyphRec),
+ ('left', FT_Int),
+ ('top', FT_Int),
+ ('bitmap', FT_Bitmap)
+ ]
+FT_BitmapGlyph = POINTER(FT_BitmapGlyphRec)
diff --git a/third_party/freetype-py/freetype/ft_types.py b/third_party/freetype-py/freetype/ft_types.py
new file mode 100644
index 0000000..8ae0f19
--- /dev/null
+++ b/third_party/freetype-py/freetype/ft_types.py
@@ -0,0 +1,155 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# -----------------------------------------------------------------------------
+#
+# FreeType high-level python API - Copyright 2011 Nicolas P. Rougier
+# Distributed under the terms of the new BSD license.
+#
+# -----------------------------------------------------------------------------
+'''
+Freetype basic data types
+-------------------------
+
+FT_Byte : A simple typedef for the unsigned char type.
+
+FT_Bytes : A typedef for constant memory areas.
+
+FT_Char : A simple typedef for the signed char type.
+
+FT_Int : A typedef for the int type.
+
+FT_UInt : A typedef for the unsigned int type.
+
+FT_Int16 : A typedef for a 16bit signed integer type.
+
+FT_UInt16 : A typedef for a 16bit unsigned integer type.
+
+FT_Int32 : A typedef for a 32bit signed integer type.
+
+FT_UInt32 : A typedef for a 32bit unsigned integer type.
+
+FT_Short : A typedef for signed short.
+
+FT_UShort : A typedef for unsigned short.
+
+FT_Long : A typedef for signed long.
+
+FT_ULong : A typedef for unsigned long.
+
+FT_Bool : A typedef of unsigned char, used for simple booleans. As usual,
+ values 1 and 0 represent true and false, respectively.
+
+FT_Offset : This is equivalent to the ANSI C 'size_t' type, i.e., the largest
+ unsigned integer type used to express a file size or position, or
+ a memory block size.
+
+FT_PtrDist : This is equivalent to the ANSI C 'ptrdiff_t' type, i.e., the
+ largest signed integer type used to express the distance between
+ two pointers.
+
+FT_String : A simple typedef for the char type, usually used for strings.
+
+FT_Tag : A typedef for 32-bit tags (as used in the SFNT format).
+
+FT_Error : The FreeType error code type. A value of 0 is always interpreted as
+ a successful operation.
+
+FT_Fixed : This type is used to store 16.16 fixed float values, like scaling
+ values or matrix coefficients.
+
+FT_Pointer : A simple typedef for a typeless pointer.
+
+FT_Pos : The type FT_Pos is used to store vectorial coordinates. Depending on
+ the context, these can represent distances in integer font units, or
+ 16.16, or 26.6 fixed float pixel coordinates.
+
+FT_FWord : A signed 16-bit integer used to store a distance in original font
+ units.
+
+FT_UFWord : An unsigned 16-bit integer used to store a distance in original
+ font units.
+
+FT_F2Dot14 : A signed 2.14 fixed float type used for unit vectors.
+
+FT_F26Dot6 : A signed 26.6 fixed float type used for vectorial pixel
+ coordinates.
+'''
+from ctypes import *
+
+
+FT_Byte = c_ubyte # A simple typedef for the unsigned char type.
+
+FT_Bytes = c_char_p # A typedef for constant memory areas.
+
+FT_Char = c_char # A simple typedef for the signed char type.
+
+FT_Int = c_int # A typedef for the int type.
+
+FT_UInt = c_uint # A typedef for the unsigned int type.
+
+FT_Int16 = c_short # A typedef for a 16bit signed integer type.
+
+FT_UInt16 = c_ushort # A typedef for a 16bit unsigned integer type.
+
+FT_Int32 = c_int32 # A typedef for a 32bit signed integer type.
+
+FT_UInt32 = c_uint32 # A typedef for a 32bit unsigned integer type.
+
+FT_Short = c_short # A typedef for signed short.
+
+FT_UShort = c_ushort # A typedef for unsigned short.
+
+FT_Long = c_long # A typedef for signed long.
+
+FT_ULong = c_ulong # A typedef for unsigned long.
+
+FT_Bool = c_char # A typedef of unsigned char, used for simple booleans. As
+ # usual, values 1 and 0 represent true and false,
+ # respectively.
+
+FT_Offset = c_size_t # This is equivalent to the ANSI C 'size_t' type, i.e.,
+ # the largest unsigned integer type used to express a file
+ # size or position, or a memory block size.
+
+FT_PtrDist = c_longlong # This is equivalent to the ANSI C 'ptrdiff_t' type,
+ # i.e., the largest signed integer type used to express
+ # the distance between two pointers.
+
+FT_String = c_char # A simple typedef for the char type, usually used for strings.
+
+FT_String_p= c_char_p
+
+FT_Tag = FT_UInt32 # A typedef for 32-bit tags (as used in the SFNT format).
+
+FT_Error = c_int # The FreeType error code type. A value of 0 is always
+ # interpreted as a successful operation.
+
+FT_Fixed = c_long # This type is used to store 16.16 fixed float values,
+ # like scaling values or matrix coefficients.
+
+FT_Pointer = c_void_p # A simple typedef for a typeless pointer.
+
+FT_Pos = c_long # The type FT_Pos is used to store vectorial
+ # coordinates. Depending on the context, these can
+ # represent distances in integer font units, or 16.16, or
+ # 26.6 fixed float pixel coordinates.
+
+FT_FWord = c_short # A signed 16-bit integer used to store a distance in
+ # original font units.
+
+FT_UFWord = c_ushort # An unsigned 16-bit integer used to store a distance in
+ # original font units.
+
+FT_F2Dot14 = c_short # A signed 2.14 fixed float type used for unit vectors.
+
+FT_F26Dot6 = c_long # A signed 26.6 fixed float type used for vectorial pixel
+ # coordinates.
+
+FT_Glyph_Format = c_int
+
+FT_Encoding = c_int
+
+
+# Describe a function used to destroy the 'client' data of any FreeType
+# object. See the description of the FT_Generic type for details of usage.
+FT_Generic_Finalizer = CFUNCTYPE(None, c_void_p)
diff --git a/third_party/freetype-py/setup.py b/third_party/freetype-py/setup.py
new file mode 100755
index 0000000..dbfad21
--- /dev/null
+++ b/third_party/freetype-py/setup.py
@@ -0,0 +1,36 @@
+#!/usr/bin/env python
+# -----------------------------------------------------------------------------
+# FreeType high-level python API - copyright 2011 Nicolas P. Rougier
+# Distributed under the terms of the new BSD license.
+# -----------------------------------------------------------------------------
+from distutils.core import setup
+from os import path
+from codecs import open
+
+here = path.abspath(path.dirname(__file__))
+with open(path.join(here, 'README.rst'), encoding='utf-8') as f:
+ long_description = f.read()
+
+setup( name = 'freetype-py',
+ version = '0.5.1',
+ description = 'Freetype python bindings',
+ long_description = long_description,
+ author = 'Nicolas P. Rougier',
+ author_email= 'Nicolas.Rougier@inria.fr',
+ url = 'https://github.com/rougier/freetype-py',
+ packages = ['freetype', 'freetype.ft_enums'],
+ classifiers = [
+ 'Development Status :: 5 - Production/Stable',
+ 'Environment :: X11 Applications',
+ 'Environment :: MacOS X',
+ 'Intended Audience :: Developers',
+ 'License :: OSI Approved :: GNU General Public License (GPL)',
+ 'Operating System :: MacOS',
+ 'Operating System :: Microsoft :: Windows',
+ 'Operating System :: POSIX',
+ 'Operating System :: Unix',
+ 'Programming Language :: Python :: 2',
+ 'Programming Language :: Python :: 3',
+ 'Topic :: Multimedia :: Graphics',
+ ],
+ )