_backend_pdf_ps.py 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. """
  2. Common functionality between the PDF and PS backends.
  3. """
  4. import functools
  5. import matplotlib as mpl
  6. from .. import font_manager, ft2font
  7. from ..afm import AFM
  8. from ..backend_bases import RendererBase
  9. @functools.lru_cache(50)
  10. def _cached_get_afm_from_fname(fname):
  11. with open(fname, "rb") as fh:
  12. return AFM(fh)
  13. class RendererPDFPSBase(RendererBase):
  14. # The following attributes must be defined by the subclasses:
  15. # - _afm_font_dir
  16. # - _use_afm_rc_name
  17. def flipy(self):
  18. # docstring inherited
  19. return False # y increases from bottom to top.
  20. def option_scale_image(self):
  21. # docstring inherited
  22. return True # PDF and PS support arbitrary image scaling.
  23. def option_image_nocomposite(self):
  24. # docstring inherited
  25. # Decide whether to composite image based on rcParam value.
  26. return not mpl.rcParams["image.composite_image"]
  27. def get_canvas_width_height(self):
  28. # docstring inherited
  29. return self.width * 72.0, self.height * 72.0
  30. def get_text_width_height_descent(self, s, prop, ismath):
  31. # docstring inherited
  32. if mpl.rcParams["text.usetex"]:
  33. texmanager = self.get_texmanager()
  34. fontsize = prop.get_size_in_points()
  35. w, h, d = texmanager.get_text_width_height_descent(
  36. s, fontsize, renderer=self)
  37. return w, h, d
  38. elif ismath:
  39. parse = self.mathtext_parser.parse(s, 72, prop)
  40. return parse.width, parse.height, parse.depth
  41. elif mpl.rcParams[self._use_afm_rc_name]:
  42. font = self._get_font_afm(prop)
  43. l, b, w, h, d = font.get_str_bbox_and_descent(s)
  44. scale = prop.get_size_in_points() / 1000
  45. w *= scale
  46. h *= scale
  47. d *= scale
  48. return w, h, d
  49. else:
  50. font = self._get_font_ttf(prop)
  51. font.set_text(s, 0.0, flags=ft2font.LOAD_NO_HINTING)
  52. w, h = font.get_width_height()
  53. d = font.get_descent()
  54. scale = 1 / 64
  55. w *= scale
  56. h *= scale
  57. d *= scale
  58. return w, h, d
  59. def _get_font_afm(self, prop):
  60. fname = (
  61. font_manager.findfont(
  62. prop, fontext="afm", directory=self._afm_font_dir)
  63. or font_manager.findfont(
  64. "Helvetica", fontext="afm", directory=self._afm_font_dir))
  65. return _cached_get_afm_from_fname(fname)
  66. def _get_font_ttf(self, prop):
  67. fname = font_manager.findfont(prop)
  68. font = font_manager.get_font(fname)
  69. font.clear()
  70. font.set_size(prop.get_size_in_points(), 72)
  71. return font