diff --git a/INSTALL b/INSTALL index a81ae7e1a104..02e5946e89d5 100644 --- a/INSTALL +++ b/INSTALL @@ -214,6 +214,10 @@ libpng 1.2 (or later) ``cycler`` 0.9 or later Composable cycle class used for constructing style-cycles +`functools32` + Required for compatibility if running on versions of Python before + Python 3.2. + Optional GUI framework ^^^^^^^^^^^^^^^^^^^^^^ diff --git a/lib/matplotlib/_mathtext_data.py b/lib/matplotlib/_mathtext_data.py index 438686005f16..a8379e30c9b3 100644 --- a/lib/matplotlib/_mathtext_data.py +++ b/lib/matplotlib/_mathtext_data.py @@ -8,250 +8,238 @@ from matplotlib.externals import six -""" -from matplotlib.ft2font import FT2Font -font = FT2Font('/usr/local/share/matplotlib/cmr10.ttf') -items = font.get_charmap().items() -items.sort() - -for charcode, glyphind in items: - print charcode, glyphind -""" - latex_to_bakoma = { - r'\oint' : ('cmex10', 45), - r'\bigodot' : ('cmex10', 50), - r'\bigoplus' : ('cmex10', 55), - r'\bigotimes' : ('cmex10', 59), - r'\sum' : ('cmex10', 51), - r'\prod' : ('cmex10', 24), - r'\int' : ('cmex10', 56), - r'\bigcup' : ('cmex10', 28), - r'\bigcap' : ('cmex10', 60), - r'\biguplus' : ('cmex10', 32), - r'\bigwedge' : ('cmex10', 4), - r'\bigvee' : ('cmex10', 37), - r'\coprod' : ('cmex10', 42), - r'\__sqrt__' : ('cmex10', 48), - r'\leftbrace' : ('cmex10', 92), - r'{' : ('cmex10', 92), - r'\{' : ('cmex10', 92), - r'\rightbrace' : ('cmex10', 130), - r'}' : ('cmex10', 130), - r'\}' : ('cmex10', 130), - r'\leftangle' : ('cmex10', 97), - r'\rightangle' : ('cmex10', 64), - r'\langle' : ('cmex10', 97), - r'\rangle' : ('cmex10', 64), - r'\widehat' : ('cmex10', 15), - r'\widetilde' : ('cmex10', 52), - r'\widebar' : ('cmr10', 131), + '\\__sqrt__' : ('cmex10', 0x70), + '\\bigcap' : ('cmex10', 0x5c), + '\\bigcup' : ('cmex10', 0x5b), + '\\bigodot' : ('cmex10', 0x4b), + '\\bigoplus' : ('cmex10', 0x4d), + '\\bigotimes' : ('cmex10', 0x4f), + '\\biguplus' : ('cmex10', 0x5d), + '\\bigvee' : ('cmex10', 0x5f), + '\\bigwedge' : ('cmex10', 0x5e), + '\\coprod' : ('cmex10', 0x61), + '\\int' : ('cmex10', 0x5a), + '\\langle' : ('cmex10', 0xad), + '\\leftangle' : ('cmex10', 0xad), + '\\leftbrace' : ('cmex10', 0xa9), + '\\oint' : ('cmex10', 0x49), + '\\prod' : ('cmex10', 0x59), + '\\rangle' : ('cmex10', 0xae), + '\\rightangle' : ('cmex10', 0xae), + '\\rightbrace' : ('cmex10', 0xaa), + '\\sum' : ('cmex10', 0x58), + '\\widehat' : ('cmex10', 0x62), + '\\widetilde' : ('cmex10', 0x65), + '\\{' : ('cmex10', 0xa9), + '\\}' : ('cmex10', 0xaa), + '{' : ('cmex10', 0xa9), + '}' : ('cmex10', 0xaa), - r'\omega' : ('cmmi10', 29), - r'\varepsilon' : ('cmmi10', 20), - r'\vartheta' : ('cmmi10', 22), - r'\varrho' : ('cmmi10', 61), - r'\varsigma' : ('cmmi10', 41), - r'\varphi' : ('cmmi10', 6), - r'\leftharpoonup' : ('cmmi10', 108), - r'\leftharpoondown' : ('cmmi10', 68), - r'\rightharpoonup' : ('cmmi10', 117), - r'\rightharpoondown' : ('cmmi10', 77), - r'\triangleright' : ('cmmi10', 130), - r'\triangleleft' : ('cmmi10', 89), - r'.' : ('cmmi10', 51), - r',' : ('cmmi10', 44), - r'<' : ('cmmi10', 99), - r'/' : ('cmmi10', 98), - r'>' : ('cmmi10', 107), - r'\flat' : ('cmmi10', 131), - r'\natural' : ('cmmi10', 90), - r'\sharp' : ('cmmi10', 50), - r'\smile' : ('cmmi10', 97), - r'\frown' : ('cmmi10', 58), - r'\ell' : ('cmmi10', 102), - r'\imath' : ('cmmi10', 8), - r'\jmath' : ('cmmi10', 65), - r'\wp' : ('cmmi10', 14), - r'\alpha' : ('cmmi10', 13), - r'\beta' : ('cmmi10', 35), - r'\gamma' : ('cmmi10', 24), - r'\delta' : ('cmmi10', 38), - r'\epsilon' : ('cmmi10', 54), - r'\zeta' : ('cmmi10', 10), - r'\eta' : ('cmmi10', 5), - r'\theta' : ('cmmi10', 18), - r'\iota' : ('cmmi10', 28), - r'\lambda' : ('cmmi10', 9), - r'\mu' : ('cmmi10', 32), - r'\nu' : ('cmmi10', 34), - r'\xi' : ('cmmi10', 7), - r'\pi' : ('cmmi10', 36), - r'\kappa' : ('cmmi10', 30), - r'\rho' : ('cmmi10', 39), - r'\sigma' : ('cmmi10', 21), - r'\tau' : ('cmmi10', 43), - '\\upsilon' : ('cmmi10', 25), - r'\phi' : ('cmmi10', 42), - r'\chi' : ('cmmi10', 17), - r'\psi' : ('cmmi10', 31), - r'|' : ('cmsy10', 47), - r'\|' : ('cmsy10', 44), - r'(' : ('cmr10', 119), - r'\leftparen' : ('cmr10', 119), - r'\rightparen' : ('cmr10', 68), - r')' : ('cmr10', 68), - r'+' : ('cmr10', 76), - r'0' : ('cmr10', 40), - r'1' : ('cmr10', 100), - r'2' : ('cmr10', 49), - r'3' : ('cmr10', 110), - r'4' : ('cmr10', 59), - r'5' : ('cmr10', 120), - r'6' : ('cmr10', 69), - r'7' : ('cmr10', 127), - r'8' : ('cmr10', 77), - r'9' : ('cmr10', 22), - r':' : ('cmr10', 85), - r';' : ('cmr10', 31), - r'=' : ('cmr10', 41), - r'\leftbracket' : ('cmr10', 62), - r'[' : ('cmr10', 62), - r'\rightbracket' : ('cmr10', 72), - r']' : ('cmr10', 72), - r'\%' : ('cmr10', 48), - r'%' : ('cmr10', 48), - r'\$' : ('cmr10', 99), - r'@' : ('cmr10', 111), - r'\#' : ('cmr10', 39), - r'\_' : ('cmtt10', 79), - r'\Gamma' : ('cmr10', 19), - r'\Delta' : ('cmr10', 6), - r'\Theta' : ('cmr10', 7), - r'\Lambda' : ('cmr10', 14), - r'\Xi' : ('cmr10', 3), - r'\Pi' : ('cmr10', 17), - r'\Sigma' : ('cmr10', 10), - '\\Upsilon' : ('cmr10', 11), - r'\Phi' : ('cmr10', 9), - r'\Psi' : ('cmr10', 15), - r'\Omega' : ('cmr10', 12), + ',' : ('cmmi10', 0x3b), + '.' : ('cmmi10', 0x3a), + '/' : ('cmmi10', 0x3d), + '<' : ('cmmi10', 0x3c), + '>' : ('cmmi10', 0x3e), + '\\alpha' : ('cmmi10', 0xae), + '\\beta' : ('cmmi10', 0xaf), + '\\chi' : ('cmmi10', 0xc2), + '\\combiningrightarrowabove' : ('cmmi10', 0x7e), + '\\delta' : ('cmmi10', 0xb1), + '\\ell' : ('cmmi10', 0x60), + '\\epsilon' : ('cmmi10', 0xb2), + '\\eta' : ('cmmi10', 0xb4), + '\\flat' : ('cmmi10', 0x5b), + '\\frown' : ('cmmi10', 0x5f), + '\\gamma' : ('cmmi10', 0xb0), + '\\imath' : ('cmmi10', 0x7b), + '\\iota' : ('cmmi10', 0xb6), + '\\jmath' : ('cmmi10', 0x7c), + '\\kappa' : ('cmmi10', 0x2219), + '\\lambda' : ('cmmi10', 0xb8), + '\\leftharpoondown' : ('cmmi10', 0x29), + '\\leftharpoonup' : ('cmmi10', 0x28), + '\\mu' : ('cmmi10', 0xb9), + '\\natural' : ('cmmi10', 0x5c), + '\\nu' : ('cmmi10', 0xba), + '\\omega' : ('cmmi10', 0x21), + '\\phi' : ('cmmi10', 0xc1), + '\\pi' : ('cmmi10', 0xbc), + '\\psi' : ('cmmi10', 0xc3), + '\\rho' : ('cmmi10', 0xbd), + '\\rightharpoondown' : ('cmmi10', 0x2b), + '\\rightharpoonup' : ('cmmi10', 0x2a), + '\\sharp' : ('cmmi10', 0x5d), + '\\sigma' : ('cmmi10', 0xbe), + '\\smile' : ('cmmi10', 0x5e), + '\\tau' : ('cmmi10', 0xbf), + '\\theta' : ('cmmi10', 0xb5), + '\\triangleleft' : ('cmmi10', 0x2f), + '\\triangleright' : ('cmmi10', 0x2e), + '\\upsilon' : ('cmmi10', 0xc0), + '\\varepsilon' : ('cmmi10', 0x22), + '\\varphi' : ('cmmi10', 0x27), + '\\varrho' : ('cmmi10', 0x25), + '\\varsigma' : ('cmmi10', 0x26), + '\\vartheta' : ('cmmi10', 0x23), + '\\wp' : ('cmmi10', 0x7d), + '\\xi' : ('cmmi10', 0xbb), + '\\zeta' : ('cmmi10', 0xb3), - r'\prime' : ('cmsy10', 73), + '!' : ('cmr10', 0x21), + '%' : ('cmr10', 0x25), + '&' : ('cmr10', 0x26), + '(' : ('cmr10', 0x28), + ')' : ('cmr10', 0x29), + '+' : ('cmr10', 0x2b), + '0' : ('cmr10', 0x30), + '1' : ('cmr10', 0x31), + '2' : ('cmr10', 0x32), + '3' : ('cmr10', 0x33), + '4' : ('cmr10', 0x34), + '5' : ('cmr10', 0x35), + '6' : ('cmr10', 0x36), + '7' : ('cmr10', 0x37), + '8' : ('cmr10', 0x38), + '9' : ('cmr10', 0x39), + ':' : ('cmr10', 0x3a), + ';' : ('cmr10', 0x3b), + '=' : ('cmr10', 0x3d), + '?' : ('cmr10', 0x3f), + '@' : ('cmr10', 0x40), + '[' : ('cmr10', 0x5b), + '\\#' : ('cmr10', 0x23), + '\\$' : ('cmr10', 0x24), + '\\%' : ('cmr10', 0x25), + '\\Delta' : ('cmr10', 0xa2), + '\\Gamma' : ('cmr10', 0xa1), + '\\Lambda' : ('cmr10', 0xa4), + '\\Omega' : ('cmr10', 0xad), + '\\Phi' : ('cmr10', 0xa9), + '\\Pi' : ('cmr10', 0xa6), + '\\Psi' : ('cmr10', 0xaa), + '\\Sigma' : ('cmr10', 0xa7), + '\\Theta' : ('cmr10', 0xa3), + '\\Upsilon' : ('cmr10', 0xa8), + '\\Xi' : ('cmr10', 0xa5), + '\\circumflexaccent' : ('cmr10', 0x5e), + '\\combiningacuteaccent' : ('cmr10', 0xb6), + '\\combiningbreve' : ('cmr10', 0xb8), + '\\combiningdiaeresis' : ('cmr10', 0xc4), + '\\combiningdotabove' : ('cmr10', 0x5f), + '\\combininggraveaccent' : ('cmr10', 0xb5), + '\\combiningoverline' : ('cmr10', 0xb9), + '\\combiningtilde' : ('cmr10', 0x7e), + '\\leftbracket' : ('cmr10', 0x5b), + '\\leftparen' : ('cmr10', 0x28), + '\\rightbracket' : ('cmr10', 0x5d), + '\\rightparen' : ('cmr10', 0x29), + '\\widebar' : ('cmr10', 0xb9), + ']' : ('cmr10', 0x5d), - # these are mathml names, I think. I'm just using them for the - # tex methods noted - r'\circumflexaccent' : ('cmr10', 124), # for \hat - r'\combiningbreve' : ('cmr10', 81), # for \breve - r'\combiningoverline' : ('cmr10', 131), # for \bar - r'\combininggraveaccent' : ('cmr10', 114), # for \grave - r'\combiningacuteaccent' : ('cmr10', 63), # for \accute - r'\combiningdiaeresis' : ('cmr10', 91), # for \ddot - r'\combiningtilde' : ('cmr10', 75), # for \tilde - r'\combiningrightarrowabove' : ('cmmi10', 110), # for \vec - r'\combiningdotabove' : ('cmr10', 26), # for \dot + '*' : ('cmsy10', 0xa4), + '-' : ('cmsy10', 0xa1), + '\\Downarrow' : ('cmsy10', 0x2b), + '\\Im' : ('cmsy10', 0x3d), + '\\Leftarrow' : ('cmsy10', 0x28), + '\\Leftrightarrow' : ('cmsy10', 0x2c), + '\\P' : ('cmsy10', 0x7b), + '\\Re' : ('cmsy10', 0x3c), + '\\Rightarrow' : ('cmsy10', 0x29), + '\\S' : ('cmsy10', 0x78), + '\\Uparrow' : ('cmsy10', 0x2a), + '\\Updownarrow' : ('cmsy10', 0x6d), + '\\Vert' : ('cmsy10', 0x6b), + '\\aleph' : ('cmsy10', 0x40), + '\\approx' : ('cmsy10', 0xbc), + '\\ast' : ('cmsy10', 0xa4), + '\\asymp' : ('cmsy10', 0xb3), + '\\backslash' : ('cmsy10', 0x6e), + '\\bigcirc' : ('cmsy10', 0xb0), + '\\bigtriangledown' : ('cmsy10', 0x35), + '\\bigtriangleup' : ('cmsy10', 0x34), + '\\bot' : ('cmsy10', 0x3f), + '\\bullet' : ('cmsy10', 0xb2), + '\\cap' : ('cmsy10', 0x5c), + '\\cdot' : ('cmsy10', 0xa2), + '\\circ' : ('cmsy10', 0xb1), + '\\clubsuit' : ('cmsy10', 0x7c), + '\\cup' : ('cmsy10', 0x5b), + '\\dag' : ('cmsy10', 0x79), + '\\dashv' : ('cmsy10', 0x61), + '\\ddag' : ('cmsy10', 0x7a), + '\\diamond' : ('cmsy10', 0xa6), + '\\diamondsuit' : ('cmsy10', 0x7d), + '\\div' : ('cmsy10', 0xa5), + '\\downarrow' : ('cmsy10', 0x23), + '\\emptyset' : ('cmsy10', 0x3b), + '\\equiv' : ('cmsy10', 0xb4), + '\\exists' : ('cmsy10', 0x39), + '\\forall' : ('cmsy10', 0x38), + '\\geq' : ('cmsy10', 0xb8), + '\\gg' : ('cmsy10', 0xc0), + '\\heartsuit' : ('cmsy10', 0x7e), + '\\in' : ('cmsy10', 0x32), + '\\infty' : ('cmsy10', 0x31), + '\\lbrace' : ('cmsy10', 0x66), + '\\lceil' : ('cmsy10', 0x64), + '\\leftarrow' : ('cmsy10', 0xc3), + '\\leftrightarrow' : ('cmsy10', 0x24), + '\\leq' : ('cmsy10', 0x2219), + '\\lfloor' : ('cmsy10', 0x62), + '\\ll' : ('cmsy10', 0xbf), + '\\mid' : ('cmsy10', 0x6a), + '\\mp' : ('cmsy10', 0xa8), + '\\nabla' : ('cmsy10', 0x72), + '\\nearrow' : ('cmsy10', 0x25), + '\\neg' : ('cmsy10', 0x3a), + '\\ni' : ('cmsy10', 0x33), + '\\nwarrow' : ('cmsy10', 0x2d), + '\\odot' : ('cmsy10', 0xaf), + '\\ominus' : ('cmsy10', 0xaa), + '\\oplus' : ('cmsy10', 0xa9), + '\\oslash' : ('cmsy10', 0xae), + '\\otimes' : ('cmsy10', 0xad), + '\\pm' : ('cmsy10', 0xa7), + '\\prec' : ('cmsy10', 0xc1), + '\\preceq' : ('cmsy10', 0xb9), + '\\prime' : ('cmsy10', 0x30), + '\\propto' : ('cmsy10', 0x2f), + '\\rbrace' : ('cmsy10', 0x67), + '\\rceil' : ('cmsy10', 0x65), + '\\rfloor' : ('cmsy10', 0x63), + '\\rightarrow' : ('cmsy10', 0x21), + '\\searrow' : ('cmsy10', 0x26), + '\\sim' : ('cmsy10', 0xbb), + '\\simeq' : ('cmsy10', 0x27), + '\\slash' : ('cmsy10', 0x36), + '\\spadesuit' : ('cmsy10', 0xc4), + '\\sqcap' : ('cmsy10', 0x75), + '\\sqcup' : ('cmsy10', 0x74), + '\\sqsubseteq' : ('cmsy10', 0x76), + '\\sqsupseteq' : ('cmsy10', 0x77), + '\\subset' : ('cmsy10', 0xbd), + '\\subseteq' : ('cmsy10', 0xb5), + '\\succ' : ('cmsy10', 0xc2), + '\\succeq' : ('cmsy10', 0xba), + '\\supset' : ('cmsy10', 0xbe), + '\\supseteq' : ('cmsy10', 0xb6), + '\\swarrow' : ('cmsy10', 0x2e), + '\\times' : ('cmsy10', 0xa3), + '\\to' : ('cmsy10', 0x21), + '\\top' : ('cmsy10', 0x3e), + '\\uparrow' : ('cmsy10', 0x22), + '\\updownarrow' : ('cmsy10', 0x6c), + '\\uplus' : ('cmsy10', 0x5d), + '\\vdash' : ('cmsy10', 0x60), + '\\vee' : ('cmsy10', 0x5f), + '\\vert' : ('cmsy10', 0x6a), + '\\wedge' : ('cmsy10', 0x5e), + '\\wr' : ('cmsy10', 0x6f), + '\\|' : ('cmsy10', 0x6b), + '|' : ('cmsy10', 0x6a), - r'\leftarrow' : ('cmsy10', 10), - '\\uparrow' : ('cmsy10', 25), - r'\downarrow' : ('cmsy10', 28), - r'\leftrightarrow' : ('cmsy10', 24), - r'\nearrow' : ('cmsy10', 99), - r'\searrow' : ('cmsy10', 57), - r'\simeq' : ('cmsy10', 108), - r'\Leftarrow' : ('cmsy10', 104), - r'\Rightarrow' : ('cmsy10', 112), - '\\Uparrow' : ('cmsy10', 60), - r'\Downarrow' : ('cmsy10', 68), - r'\Leftrightarrow' : ('cmsy10', 51), - r'\nwarrow' : ('cmsy10', 65), - r'\swarrow' : ('cmsy10', 116), - r'\propto' : ('cmsy10', 15), - r'\infty' : ('cmsy10', 32), - r'\in' : ('cmsy10', 59), - r'\ni' : ('cmsy10', 122), - r'\bigtriangleup' : ('cmsy10', 80), - r'\bigtriangledown' : ('cmsy10', 132), - r'\slash' : ('cmsy10', 87), - r'\forall' : ('cmsy10', 21), - r'\exists' : ('cmsy10', 5), - r'\neg' : ('cmsy10', 20), - r'\emptyset' : ('cmsy10', 33), - r'\Re' : ('cmsy10', 95), - r'\Im' : ('cmsy10', 52), - r'\top' : ('cmsy10', 100), - r'\bot' : ('cmsy10', 11), - r'\aleph' : ('cmsy10', 26), - r'\cup' : ('cmsy10', 6), - r'\cap' : ('cmsy10', 19), - '\\uplus' : ('cmsy10', 58), - r'\wedge' : ('cmsy10', 43), - r'\vee' : ('cmsy10', 96), - r'\vdash' : ('cmsy10', 109), - r'\dashv' : ('cmsy10', 66), - r'\lfloor' : ('cmsy10', 117), - r'\rfloor' : ('cmsy10', 74), - r'\lceil' : ('cmsy10', 123), - r'\rceil' : ('cmsy10', 81), - r'\lbrace' : ('cmsy10', 92), - r'\rbrace' : ('cmsy10', 105), - r'\mid' : ('cmsy10', 47), - r'\vert' : ('cmsy10', 47), - r'\Vert' : ('cmsy10', 44), - '\\updownarrow' : ('cmsy10', 94), - '\\Updownarrow' : ('cmsy10', 53), - r'\backslash' : ('cmsy10', 126), - r'\wr' : ('cmsy10', 101), - r'\nabla' : ('cmsy10', 110), - r'\sqcup' : ('cmsy10', 67), - r'\sqcap' : ('cmsy10', 118), - r'\sqsubseteq' : ('cmsy10', 75), - r'\sqsupseteq' : ('cmsy10', 124), - r'\S' : ('cmsy10', 129), - r'\dag' : ('cmsy10', 71), - r'\ddag' : ('cmsy10', 127), - r'\P' : ('cmsy10', 130), - r'\clubsuit' : ('cmsy10', 18), - r'\diamondsuit' : ('cmsy10', 34), - r'\heartsuit' : ('cmsy10', 22), - r'-' : ('cmsy10', 17), - r'\cdot' : ('cmsy10', 78), - r'\times' : ('cmsy10', 13), - r'*' : ('cmsy10', 9), - r'\ast' : ('cmsy10', 9), - r'\div' : ('cmsy10', 31), - r'\diamond' : ('cmsy10', 48), - r'\pm' : ('cmsy10', 8), - r'\mp' : ('cmsy10', 98), - r'\oplus' : ('cmsy10', 16), - r'\ominus' : ('cmsy10', 56), - r'\otimes' : ('cmsy10', 30), - r'\oslash' : ('cmsy10', 107), - r'\odot' : ('cmsy10', 64), - r'\bigcirc' : ('cmsy10', 115), - r'\circ' : ('cmsy10', 72), - r'\bullet' : ('cmsy10', 84), - r'\asymp' : ('cmsy10', 121), - r'\equiv' : ('cmsy10', 35), - r'\subseteq' : ('cmsy10', 103), - r'\supseteq' : ('cmsy10', 42), - r'\leq' : ('cmsy10', 14), - r'\geq' : ('cmsy10', 29), - r'\preceq' : ('cmsy10', 79), - r'\succeq' : ('cmsy10', 131), - r'\sim' : ('cmsy10', 27), - r'\approx' : ('cmsy10', 23), - r'\subset' : ('cmsy10', 50), - r'\supset' : ('cmsy10', 86), - r'\ll' : ('cmsy10', 85), - r'\gg' : ('cmsy10', 40), - r'\prec' : ('cmsy10', 93), - r'\succ' : ('cmsy10', 49), - r'\rightarrow' : ('cmsy10', 12), - r'\to' : ('cmsy10', 12), - r'\spadesuit' : ('cmsy10', 7), - r'?' : ('cmr10', 50), - r'!' : ('cmr10', 29), - r'&' : ('cmr10', 109) + '\\_' : ('cmtt10', 0x5f) } latex_to_cmex = { diff --git a/lib/matplotlib/backends/backend_agg.py b/lib/matplotlib/backends/backend_agg.py index f3b23ca95531..bde41f1f2a9a 100644 --- a/lib/matplotlib/backends/backend_agg.py +++ b/lib/matplotlib/backends/backend_agg.py @@ -28,13 +28,13 @@ import numpy as np from matplotlib import verbose, rcParams -from matplotlib.backend_bases import RendererBase,\ - FigureManagerBase, FigureCanvasBase +from matplotlib.backend_bases import (RendererBase, FigureManagerBase, + FigureCanvasBase) from matplotlib.cbook import is_string_like, maxdict, restrict_dict from matplotlib.figure import Figure -from matplotlib.font_manager import findfont -from matplotlib.ft2font import FT2Font, LOAD_FORCE_AUTOHINT, LOAD_NO_HINTING, \ - LOAD_DEFAULT, LOAD_NO_AUTOHINT +from matplotlib.font_manager import findfont, get_font +from matplotlib.ft2font import (LOAD_FORCE_AUTOHINT, LOAD_NO_HINTING, + LOAD_DEFAULT, LOAD_NO_AUTOHINT) from matplotlib.mathtext import MathTextParser from matplotlib.path import Path from matplotlib.transforms import Bbox, BboxBase @@ -81,7 +81,6 @@ class RendererAgg(RendererBase): # renderer at a time lock = threading.RLock() - _fontd = maxdict(50) def __init__(self, width, height, dpi): if __debug__: verbose.report('RendererAgg.__init__', 'debug-annoying') RendererBase.__init__(self) @@ -191,6 +190,7 @@ def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None): flags = get_hinting_flag() font = self._get_agg_font(prop) + if font is None: return None if len(s) == 1 and ord(s) > 127: font.load_char(ord(s), flags=flags) @@ -272,18 +272,10 @@ def _get_agg_font(self, prop): if __debug__: verbose.report('RendererAgg._get_agg_font', 'debug-annoying') - key = hash(prop) - font = RendererAgg._fontd.get(key) - - if font is None: - fname = findfont(prop) - font = RendererAgg._fontd.get(fname) - if font is None: - font = FT2Font( - fname, - hinting_factor=rcParams['text.hinting_factor']) - RendererAgg._fontd[fname] = font - RendererAgg._fontd[key] = font + fname = findfont(prop) + font = get_font( + fname, + hinting_factor=rcParams['text.hinting_factor']) font.clear() size = prop.get_size_in_points() diff --git a/lib/matplotlib/backends/backend_pdf.py b/lib/matplotlib/backends/backend_pdf.py index 0ef7c1c49634..acba9795ae2a 100644 --- a/lib/matplotlib/backends/backend_pdf.py +++ b/lib/matplotlib/backends/backend_pdf.py @@ -29,18 +29,18 @@ import matplotlib from matplotlib import __version__, rcParams from matplotlib._pylab_helpers import Gcf -from matplotlib.backend_bases import RendererBase, GraphicsContextBase,\ - FigureManagerBase, FigureCanvasBase +from matplotlib.backend_bases import (RendererBase, GraphicsContextBase, + FigureManagerBase, FigureCanvasBase) from matplotlib.backends.backend_mixed import MixedModeRenderer -from matplotlib.cbook import Bunch, is_string_like, \ - get_realpath_and_stat, is_writable_file_like, maxdict +from matplotlib.cbook import (Bunch, is_string_like, get_realpath_and_stat, + is_writable_file_like, maxdict) from matplotlib.figure import Figure -from matplotlib.font_manager import findfont, is_opentype_cff_font +from matplotlib.font_manager import findfont, is_opentype_cff_font, get_font from matplotlib.afm import AFM import matplotlib.type1font as type1font import matplotlib.dviread as dviread -from matplotlib.ft2font import FT2Font, FIXED_WIDTH, ITALIC, LOAD_NO_SCALE, \ - LOAD_NO_HINTING, KERNING_UNFITTED +from matplotlib.ft2font import (FIXED_WIDTH, ITALIC, LOAD_NO_SCALE, + LOAD_NO_HINTING, KERNING_UNFITTED) from matplotlib.mathtext import MathTextParser from matplotlib.transforms import Affine2D, BboxBase from matplotlib.path import Path @@ -757,7 +757,7 @@ def createType1Descriptor(self, t1font, fontfile): if 0: flags |= 1 << 18 - ft2font = FT2Font(fontfile) + ft2font = get_font(fontfile) descriptor = { 'Type': Name('FontDescriptor'), @@ -817,7 +817,7 @@ def _get_xobject_symbol_name(self, filename, symbol_name): def embedTTF(self, filename, characters): """Embed the TTF font from the named file into the document.""" - font = FT2Font(filename) + font = get_font(filename) fonttype = rcParams['pdf.fonttype'] def cvt(length, upe=font.units_per_EM, nearest=True): @@ -1526,7 +1526,6 @@ def writeTrailer(self): class RendererPdf(RendererBase): - truetype_font_cache = maxdict(50) afm_font_cache = maxdict(50) def __init__(self, file, image_dpi): @@ -2126,15 +2125,8 @@ def _get_font_afm(self, prop): return font def _get_font_ttf(self, prop): - key = hash(prop) - font = self.truetype_font_cache.get(key) - if font is None: - filename = findfont(prop) - font = self.truetype_font_cache.get(filename) - if font is None: - font = FT2Font(filename) - self.truetype_font_cache[filename] = font - self.truetype_font_cache[key] = font + filename = findfont(prop) + font = get_font(filename) font.clear() font.set_size(prop.get_size_in_points(), 72) return font diff --git a/lib/matplotlib/backends/backend_pgf.py b/lib/matplotlib/backends/backend_pgf.py index ce00652e1388..4f00ea0b43ab 100644 --- a/lib/matplotlib/backends/backend_pgf.py +++ b/lib/matplotlib/backends/backend_pgf.py @@ -36,10 +36,9 @@ system_fonts = [] if sys.platform.startswith('win'): from matplotlib import font_manager - from matplotlib.ft2font import FT2Font for f in font_manager.win32InstalledFonts(): try: - system_fonts.append(FT2Font(str(f)).family_name) + system_fonts.append(font_manager.get_font(str(f)).family_name) except: pass # unknown error, skip this font else: diff --git a/lib/matplotlib/backends/backend_ps.py b/lib/matplotlib/backends/backend_ps.py index 3f1145a5b14e..bb6f83afc667 100644 --- a/lib/matplotlib/backends/backend_ps.py +++ b/lib/matplotlib/backends/backend_ps.py @@ -28,8 +28,8 @@ def _fn_name(): return sys._getframe(1).f_code.co_name is_writable_file_like, maxdict, file_requires_unicode from matplotlib.figure import Figure -from matplotlib.font_manager import findfont, is_opentype_cff_font -from matplotlib.ft2font import FT2Font, KERNING_DEFAULT, LOAD_NO_HINTING +from matplotlib.font_manager import findfont, is_opentype_cff_font, get_font +from matplotlib.ft2font import KERNING_DEFAULT, LOAD_NO_HINTING from matplotlib.ttconv import convert_ttf_to_ps from matplotlib.mathtext import MathTextParser from matplotlib._mathtext_data import uni2type1 @@ -199,7 +199,6 @@ class RendererPS(RendererBase): context instance that controls the colors/styles. """ - fontd = maxdict(50) afmfontd = maxdict(50) def __init__(self, width, height, pswriter, imagedpi=72): @@ -393,15 +392,8 @@ def _get_font_afm(self, prop): return font def _get_font_ttf(self, prop): - key = hash(prop) - font = self.fontd.get(key) - if font is None: - fname = findfont(prop) - font = self.fontd.get(fname) - if font is None: - font = FT2Font(fname) - self.fontd[fname] = font - self.fontd[key] = font + fname = findfont(prop) + font = get_font(fname) font.clear() size = prop.get_size_in_points() font.set_size(size, 72.0) @@ -1145,7 +1137,7 @@ def print_figure_impl(): if not rcParams['ps.useafm']: for font_filename, chars in six.itervalues(ps_renderer.used_characters): if len(chars): - font = FT2Font(font_filename) + font = get_font(font_filename) cmap = font.get_charmap() glyph_ids = [] for c in chars: diff --git a/lib/matplotlib/backends/backend_svg.py b/lib/matplotlib/backends/backend_svg.py index 4e137936b96d..9c59c8bbbfee 100644 --- a/lib/matplotlib/backends/backend_svg.py +++ b/lib/matplotlib/backends/backend_svg.py @@ -19,8 +19,8 @@ from matplotlib.cbook import is_string_like, is_writable_file_like, maxdict from matplotlib.colors import rgb2hex from matplotlib.figure import Figure -from matplotlib.font_manager import findfont, FontProperties -from matplotlib.ft2font import FT2Font, KERNING_DEFAULT, LOAD_NO_HINTING +from matplotlib.font_manager import findfont, FontProperties, get_font +from matplotlib.ft2font import KERNING_DEFAULT, LOAD_NO_HINTING from matplotlib.mathtext import MathTextParser from matplotlib.path import Path from matplotlib import _path @@ -326,15 +326,8 @@ def _make_flip_transform(self, transform): .translate(0.0, self.height)) def _get_font(self, prop): - key = hash(prop) - font = self.fontd.get(key) - if font is None: - fname = findfont(prop) - font = self.fontd.get(fname) - if font is None: - font = FT2Font(fname) - self.fontd[fname] = font - self.fontd[key] = font + fname = findfont(prop) + font = get_font(fname) font.clear() size = prop.get_size_in_points() font.set_size(size, 72.0) @@ -495,7 +488,7 @@ def _write_svgfonts(self): writer = self.writer writer.start('defs') for font_fname, chars in six.iteritems(self._fonts): - font = FT2Font(font_fname) + font = get_font(font_fname) font.set_size(72, 72) sfnt = font.get_sfnt() writer.start('font', id=sfnt[(1, 0, 0, 4)]) diff --git a/lib/matplotlib/font_manager.py b/lib/matplotlib/font_manager.py index 7bba3b8ae3ae..1dfae5e10c97 100644 --- a/lib/matplotlib/font_manager.py +++ b/lib/matplotlib/font_manager.py @@ -63,6 +63,12 @@ from matplotlib.fontconfig_pattern import \ parse_fontconfig_pattern, generate_fontconfig_pattern +try: + from functools import lru_cache +except ImportError: + from functools32 import lru_cache + + USE_FONTCONFIG = False verbose = matplotlib.verbose @@ -733,7 +739,7 @@ def get_name(self): Return the name of the font that best matches the font properties. """ - return ft2font.FT2Font(findfont(self)).family_name + return get_font(findfont(self)).family_name def get_style(self): """ @@ -1336,7 +1342,6 @@ def findfont(self, prop, fontext='ttf', directory=None, _lookup_cache[fontext].set(prop, result) return result - _is_opentype_cff_font_cache = {} def is_opentype_cff_font(filename): """ @@ -1357,6 +1362,10 @@ def is_opentype_cff_font(filename): fontManager = None _fmcache = None + +get_font = lru_cache(64)(ft2font.FT2Font) + + # The experimental fontconfig-based backend. if USE_FONTCONFIG and sys.platform != 'win32': import re diff --git a/lib/matplotlib/mathtext.py b/lib/matplotlib/mathtext.py index 90e45a3c4d75..b9f15cf6a621 100644 --- a/lib/matplotlib/mathtext.py +++ b/lib/matplotlib/mathtext.py @@ -33,10 +33,10 @@ import numpy as np import pyparsing -from pyparsing import Combine, Group, Optional, Forward, \ - Literal, OneOrMore, ZeroOrMore, ParseException, Empty, \ - ParseResults, Suppress, oneOf, StringEnd, ParseFatalException, \ - FollowedBy, Regex, ParserElement, QuotedString, ParseBaseException +from pyparsing import (Combine, Group, Optional, Forward, + Literal, OneOrMore, ZeroOrMore, ParseException, Empty, + ParseResults, Suppress, oneOf, StringEnd, ParseFatalException, + FollowedBy, Regex, ParserElement, QuotedString, ParseBaseException) # Enable packrat parsing if (six.PY3 and @@ -48,12 +48,14 @@ ParserElement.enablePackrat() from matplotlib.afm import AFM -from matplotlib.cbook import Bunch, get_realpath_and_stat, \ - is_string_like, maxdict -from matplotlib.ft2font import FT2Font, FT2Image, KERNING_DEFAULT, LOAD_FORCE_AUTOHINT, LOAD_NO_HINTING -from matplotlib.font_manager import findfont, FontProperties -from matplotlib._mathtext_data import latex_to_bakoma, \ - latex_to_standard, tex2uni, latex_to_cmex, stix_virtual_fonts +from matplotlib.cbook import (Bunch, get_realpath_and_stat, is_string_like, + maxdict) +from matplotlib.ft2font import (FT2Image, KERNING_DEFAULT, LOAD_FORCE_AUTOHINT, + LOAD_NO_HINTING) +from matplotlib.font_manager import findfont, FontProperties, get_font +from matplotlib._mathtext_data import (latex_to_bakoma, latex_to_standard, + tex2uni, latex_to_cmex, + stix_virtual_fonts) from matplotlib import get_data_path, rcParams import matplotlib.colors as mcolors @@ -547,23 +549,13 @@ class TruetypeFonts(Fonts): A generic base class for all font setups that use Truetype fonts (through FT2Font). """ - class CachedFont: - def __init__(self, font): - self.font = font - self.charmap = font.get_charmap() - self.glyphmap = dict( - [(glyphind, ccode) for ccode, glyphind in six.iteritems(self.charmap)]) - - def __repr__(self): - return repr(self.font) - def __init__(self, default_font_prop, mathtext_backend): Fonts.__init__(self, default_font_prop, mathtext_backend) self.glyphd = {} self._fonts = {} filename = findfont(default_font_prop) - default_font = self.CachedFont(FT2Font(filename)) + default_font = get_font(filename) self._fonts['default'] = default_font self._fonts['regular'] = default_font @@ -576,18 +568,16 @@ def _get_font(self, font): basename = self.fontmap[font] else: basename = font - cached_font = self._fonts.get(basename) if cached_font is None and os.path.exists(basename): - font = FT2Font(basename) - cached_font = self.CachedFont(font) + cached_font = get_font(basename) self._fonts[basename] = cached_font - self._fonts[font.postscript_name] = cached_font - self._fonts[font.postscript_name.lower()] = cached_font + self._fonts[cached_font.postscript_name] = cached_font + self._fonts[cached_font.postscript_name.lower()] = cached_font return cached_font - def _get_offset(self, cached_font, glyph, fontsize, dpi): - if cached_font.font.postscript_name == 'Cmex10': + def _get_offset(self, font, glyph, fontsize, dpi): + if font.postscript_name == 'Cmex10': return ((glyph.height/64.0/2.0) + (fontsize/3.0 * dpi/72.0)) return 0. @@ -597,17 +587,16 @@ def _get_info(self, fontname, font_class, sym, fontsize, dpi): if bunch is not None: return bunch - cached_font, num, symbol_name, fontsize, slanted = \ + font, num, symbol_name, fontsize, slanted = \ self._get_glyph(fontname, font_class, sym, fontsize) - font = cached_font.font font.set_size(fontsize, dpi) glyph = font.load_char( num, flags=self.mathtext_backend.get_hinting_type()) xmin, ymin, xmax, ymax = [val/64.0 for val in glyph.bbox] - offset = self._get_offset(cached_font, glyph, fontsize, dpi) + offset = self._get_offset(font, glyph, fontsize, dpi) metrics = Bunch( advance = glyph.linearHoriAdvance/65536.0, height = glyph.height/64.0, @@ -633,13 +622,13 @@ def _get_info(self, fontname, font_class, sym, fontsize, dpi): ) return result - def get_xheight(self, font, fontsize, dpi): - cached_font = self._get_font(font) - cached_font.font.set_size(fontsize, dpi) - pclt = cached_font.font.get_sfnt_table('pclt') + def get_xheight(self, fontname, fontsize, dpi): + font = self._get_font(fontname) + font.set_size(fontsize, dpi) + pclt = font.get_sfnt_table('pclt') if pclt is None: # Some fonts don't store the xHeight, so we do a poor man's xHeight - metrics = self.get_metrics(font, rcParams['mathtext.default'], 'x', fontsize, dpi) + metrics = self.get_metrics(fontname, rcParams['mathtext.default'], 'x', fontsize, dpi) return metrics.iceberg xHeight = (pclt['xHeight'] / 64.0) * (fontsize / 12.0) * (dpi / 100.0) return xHeight @@ -691,28 +680,27 @@ def __init__(self, *args, **kwargs): def _get_glyph(self, fontname, font_class, sym, fontsize): symbol_name = None + font = None if fontname in self.fontmap and sym in latex_to_bakoma: basename, num = latex_to_bakoma[sym] slanted = (basename == "cmmi10") or sym in self._slanted_symbols - cached_font = self._get_font(basename) - if cached_font is not None: - symbol_name = cached_font.font.get_glyph_name(num) - num = cached_font.glyphmap[num] + font = self._get_font(basename) elif len(sym) == 1: slanted = (fontname == "it") - cached_font = self._get_font(fontname) - if cached_font is not None: + font = self._get_font(fontname) + if font is not None: num = ord(sym) - gid = cached_font.charmap.get(num) - if gid is not None: - symbol_name = cached_font.font.get_glyph_name( - cached_font.charmap[num]) + + if font is not None: + gid = font.get_char_index(num) + if gid != 0: + symbol_name = font.get_glyph_name(gid) if symbol_name is None: return self._stix_fallback._get_glyph( fontname, font_class, sym, fontsize) - return cached_font, num, symbol_name, fontsize, slanted + return font, num, symbol_name, fontsize, slanted # The Bakoma fonts contain many pre-sized alternatives for the # delimiters. The AutoSizedChar class will use these alternatives @@ -843,10 +831,10 @@ def _get_glyph(self, fontname, font_class, sym, fontsize): slanted = (new_fontname == 'it') or sym in self._slanted_symbols found_symbol = False - cached_font = self._get_font(new_fontname) - if cached_font is not None: + font = self._get_font(new_fontname) + if font is not None: try: - glyphindex = cached_font.charmap[uniindex] + glyphindex = font.get_char_index(uniindex) found_symbol = True except KeyError: pass @@ -860,19 +848,21 @@ def _get_glyph(self, fontname, font_class, sym, fontsize): else: if fontname in ('it', 'regular') and isinstance(self, StixFonts): return self._get_glyph('rm', font_class, sym, fontsize) - warn("Font '%s' does not have a glyph for '%s' [U%x]" % - (new_fontname, sym.encode('ascii', 'backslashreplace'), uniindex), + warn("Font '%s' does not have a glyph for '%s' [U+%x]" % + (new_fontname, + sym.encode('ascii', 'backslashreplace').decode('ascii'), + uniindex), MathTextWarning) warn("Substituting with a dummy symbol.", MathTextWarning) fontname = 'rm' new_fontname = fontname - cached_font = self._get_font(fontname) + font = self._get_font(fontname) uniindex = 0xA4 # currency character, for lack of anything better - glyphindex = cached_font.charmap[uniindex] + glyphindex = font.get_char_index(uniindex) slanted = False - symbol_name = cached_font.font.get_glyph_name(glyphindex) - return cached_font, uniindex, symbol_name, fontsize, slanted + symbol_name = font.get_glyph_name(glyphindex) + return font, uniindex, symbol_name, fontsize, slanted def get_sized_alternatives_for_symbol(self, fontname, sym): if self.cm_fallback: @@ -983,9 +973,9 @@ def get_sized_alternatives_for_symbol(self, fontname, sym): uniindex = fix_ups.get(uniindex, uniindex) for i in range(6): - cached_font = self._get_font(i) - glyphindex = cached_font.charmap.get(uniindex) - if glyphindex is not None: + font = self._get_font(i) + glyphindex = font.get_char_index(uniindex) + if glyphindex != 0: alternatives.append((i, unichr_safe(uniindex))) # The largest size of the radical symbol in STIX has incorrect @@ -1145,12 +1135,13 @@ def get_kern(self, font1, fontclass1, sym1, fontsize1, font2, fontclass2, sym2, fontsize2, dpi) def get_xheight(self, font, fontsize, dpi): - cached_font = self._get_font(font) - return cached_font.get_xheight() * 0.001 * fontsize + font = self._get_font(font) + return font.get_xheight() * 0.001 * fontsize def get_underline_thickness(self, font, fontsize, dpi): - cached_font = self._get_font(font) - return cached_font.get_underline_thickness() * 0.001 * fontsize + font = self._get_font(font) + return font.get_underline_thickness() * 0.001 * fontsize + ############################################################################## # TeX-LIKE BOX MODEL @@ -1319,7 +1310,6 @@ def __init__(self, c, state): Node.__init__(self) self.c = c self.font_output = state.font_output - assert isinstance(state.font, (six.string_types, int)) self.font = state.font self.font_class = state.font_class self.fontsize = state.fontsize diff --git a/lib/matplotlib/tests/__init__.py b/lib/matplotlib/tests/__init__.py index 20a4ae3c6087..9b06bd1cbc91 100644 --- a/lib/matplotlib/tests/__init__.py +++ b/lib/matplotlib/tests/__init__.py @@ -49,12 +49,6 @@ def setup(): rcParams['text.hinting'] = False rcParams['text.hinting_factor'] = 8 - # Clear the font caches. Otherwise, the hinting mode can travel - # from one test to another. - backend_agg.RendererAgg._fontd.clear() - backend_pdf.RendererPdf.truetype_font_cache.clear() - backend_svg.RendererSVG.fontd.clear() - def assert_str_equal(reference_str, test_str, format_str=('String {str1} and {str2} do not ' diff --git a/lib/matplotlib/textpath.py b/lib/matplotlib/textpath.py index d46dd27898b1..e0f7fbe8d400 100644 --- a/lib/matplotlib/textpath.py +++ b/lib/matplotlib/textpath.py @@ -13,11 +13,11 @@ from matplotlib.path import Path from matplotlib import rcParams import matplotlib.font_manager as font_manager -from matplotlib.ft2font import FT2Font, KERNING_DEFAULT, LOAD_NO_HINTING +from matplotlib.ft2font import KERNING_DEFAULT, LOAD_NO_HINTING from matplotlib.ft2font import LOAD_TARGET_LIGHT from matplotlib.mathtext import MathTextParser import matplotlib.dviread as dviread -from matplotlib.font_manager import FontProperties +from matplotlib.font_manager import FontProperties, get_font from matplotlib.transforms import Affine2D from matplotlib.externals.six.moves.urllib.parse import quote as urllib_quote @@ -54,7 +54,7 @@ def _get_font(self, prop): find a ttf font. """ fname = font_manager.findfont(prop) - font = FT2Font(fname) + font = get_font(fname) font.set_size(self.FONT_SCALE, self.DPI) return font @@ -334,7 +334,7 @@ def get_glyphs_tex(self, prop, s, glyph_map=None, font_bunch = self.tex_font_map[dvifont.texname] if font_and_encoding is None: - font = FT2Font(font_bunch.filename) + font = get_font(font_bunch.filename) for charmap_name, charmap_code in [("ADOBE_CUSTOM", 1094992451), diff --git a/lib/mpl_toolkits/tests/__init__.py b/lib/mpl_toolkits/tests/__init__.py index 20a4ae3c6087..9b06bd1cbc91 100644 --- a/lib/mpl_toolkits/tests/__init__.py +++ b/lib/mpl_toolkits/tests/__init__.py @@ -49,12 +49,6 @@ def setup(): rcParams['text.hinting'] = False rcParams['text.hinting_factor'] = 8 - # Clear the font caches. Otherwise, the hinting mode can travel - # from one test to another. - backend_agg.RendererAgg._fontd.clear() - backend_pdf.RendererPdf.truetype_font_cache.clear() - backend_svg.RendererSVG.fontd.clear() - def assert_str_equal(reference_str, test_str, format_str=('String {str1} and {str2} do not ' diff --git a/setup.py b/setup.py index f3ecd708f54f..b3fb0413699e 100644 --- a/setup.py +++ b/setup.py @@ -67,6 +67,7 @@ 'Required dependencies and extensions', setupext.Numpy(), setupext.Dateutil(), + setupext.FuncTools32(), setupext.Pytz(), setupext.Cycler(), setupext.Tornado(), diff --git a/setupext.py b/setupext.py index 0a9660b6f7c8..1c70adde064e 100755 --- a/setupext.py +++ b/setupext.py @@ -1221,6 +1221,29 @@ def get_install_requires(self): return [dateutil] +class FuncTools32(SetupPackage): + name = "functools32" + + def check(self): + if sys.version_info[:2] < (3, 2): + try: + import functools32 + except ImportError: + return ( + "functools32 was not found. It is required for for" + "python versions prior to 3.2") + + return "using functools32" + else: + return "Not required" + + def get_install_requires(self): + if sys.version_info[:2] < (3, 2): + return ['functools32'] + else: + return [] + + class Tornado(OptionalPackage): name = "tornado" diff --git a/src/ft2font_wrapper.cpp b/src/ft2font_wrapper.cpp index c2fd95798959..92e21bb593bf 100644 --- a/src/ft2font_wrapper.cpp +++ b/src/ft2font_wrapper.cpp @@ -954,6 +954,27 @@ static PyObject *PyFT2Font_get_charmap(PyFT2Font *self, PyObject *args, PyObject return charmap; } + +const char *PyFT2Font_get_char_index__doc__ = + "get_char_index()\n" + "\n" + "Given a character code, returns a glyph index.\n"; + +static PyObject *PyFT2Font_get_char_index(PyFT2Font *self, PyObject *args, PyObject *kwds) +{ + FT_UInt index; + FT_ULong ccode; + + if (!PyArg_ParseTuple(args, "I:get_char_index", &ccode)) { + return NULL; + } + + index = FT_Get_Char_Index(self->x->get_face(), ccode); + + return PyLong_FromLong(index); +} + + const char *PyFT2Font_get_sfnt__doc__ = "get_sfnt(name)\n" "\n" @@ -1602,6 +1623,7 @@ static PyTypeObject *PyFT2Font_init_type(PyObject *m, PyTypeObject *type) {"draw_glyph_to_bitmap", (PyCFunction)PyFT2Font_draw_glyph_to_bitmap, METH_VARARGS|METH_KEYWORDS, PyFT2Font_draw_glyph_to_bitmap__doc__}, {"get_glyph_name", (PyCFunction)PyFT2Font_get_glyph_name, METH_VARARGS, PyFT2Font_get_glyph_name__doc__}, {"get_charmap", (PyCFunction)PyFT2Font_get_charmap, METH_NOARGS, PyFT2Font_get_charmap__doc__}, + {"get_char_index", (PyCFunction)PyFT2Font_get_char_index, METH_VARARGS, PyFT2Font_get_char_index__doc__}, {"get_sfnt", (PyCFunction)PyFT2Font_get_sfnt, METH_NOARGS, PyFT2Font_get_sfnt__doc__}, {"get_name_index", (PyCFunction)PyFT2Font_get_name_index, METH_VARARGS, PyFT2Font_get_name_index__doc__}, {"get_ps_font_info", (PyCFunction)PyFT2Font_get_ps_font_info, METH_NOARGS, PyFT2Font_get_ps_font_info__doc__},