new_contents: #  Copyright (c) 2020, Manfred Moitzi
  #  License: MIT License
  """ Manage font data
  
  The default DXF way to store fonts in the STYLE entity by using the ttf file
  name is not a good choice, most render backends select fonts by their
  properties, this list shows the matplotlib properties:
  
  - family: List of font names in decreasing order of priority.
      The items may include a generic font family name, either
      'serif', 'sans-serif', 'cursive', 'fantasy', or 'monospace'.
  - style: 'normal', 'italic' or 'oblique'
  - stretch: A numeric value in the range 0-1000 or one of
      'ultra-condensed', 'extra-condensed', 'condensed',
      'semi-condensed', 'normal', 'semi-expanded', 'expanded',
      'extra-expanded' or 'ultra-expanded'
  - weight: A numeric value in the range 0-1000 or one of
      'ultralight', 'light', 'normal', 'regular', 'book', 'medium',
      'roman', 'semibold', 'demibold', 'demi', 'bold', 'heavy',
      'extra bold', 'black'.
  
  This way the backand can choose a similar font if the original font is not
  available.
  
  Select fonts in different backends:
  
  - matplotlib: FontProperties(family, style, stretch, weight)
  - pyqt:
  
  This module manages as backend agnostic font database.
  The properties of many common fonts are stored in a data file "fonts.json",
  therefore for basic usage no additional dependency is required.
  Advanced features uses the optional matplotlib font manager tools.
  
  Install matplotlib::
  
      pip install matplotlib
  
  The :func:`add_system_fonts` function adds all available fonts for the current
  system to the font database.
  
  """
  from typing import Dict, Optional
  from collections import namedtuple
  import logging
  from pathlib import Path
  import json
  
  FONT_DATA_FILE = 'fonts.json'
  logger = logging.getLogger('ezdxf')
  
  FontEntry = namedtuple('FontEntry', "family style stretch weight")
  
  # Key is TTF font file name without path in lowercase like "arial.ttf":
  fonts: Dict[str, FontEntry] = dict()
  
  
  def db_key(name: str) -> str:
      return Path(name).name.lower()
  
  
  def add_system_fonts() -> None:
      try:
          from matplotlib.font_manager import FontManager
      except ImportError:
          logger.debug('This function requires the optional matplotlib package.')
          return
      for entry in FontManager().ttflist:
          ttf = db_key(entry.fname)
          fonts[ttf] = FontEntry(
              entry.name,
              entry.style,
              entry.stretch,
              entry.weight,
          )
  
  
  def find(ttf_path: str) -> Optional[FontEntry]:
      return fonts.get(db_key(ttf_path))
  
  
  def load(path=None):
      path = Path(path) if path else Path(__file__).parent / FONT_DATA_FILE
  
      if not path.exists():
          return
      with open(path, 'rt') as fp:
          data = json.load(fp)
      if data:
          fonts.update(data)
  
  
  def save(path=None):
      path = Path(path) if path else Path(__file__).parent / FONT_DATA_FILE
      with open(path, 'wt') as fp:
          json.dump(fonts, fp, indent=2)
  
  
  load()
  
subject: add fonts.py module