# Path: weasyprint/logger.py
# LOGGER = logging.getLogger('weasyprint')
# 
# Path: weasyprint/urls.py
# FILESYSTEM_ENCODING = sys.getfilesystemencoding()
# 
# @contextlib.contextmanager
# def fetch(url_fetcher, url):
#     """Call an url_fetcher, fill in optional data, and clean up."""
#     try:
#         result = url_fetcher(url)
#     except Exception as exception:
#         raise URLFetchingError(f'{type(exception).__name__}: {exception}')
#     result.setdefault('redirected_url', url)
#     result.setdefault('mime_type', None)
#     if 'file_obj' in result:
#         try:
#             yield result
#         finally:
#             try:
#                 result['file_obj'].close()
#             except Exception:  # pragma: no cover
#                 # May already be closed or something.
#                 # This is just cleanup anyway: log but make it non-fatal.
#                 LOGGER.warning(
#                     'Error when closing stream for %s:\n%s',
#                     url, traceback.format_exc())
#     else:
#         yield result
# 
# Path: weasyprint/text/constants.py
# CAPS_KEYS = {
#     'small-caps': ['smcp'],
#     'all-small-caps': ['c2sc', 'smcp'],
#     'petite-caps': ['pcap'],
#     'all-petite-caps': ['c2pc', 'pcap'],
#     'unicase': ['unic'],
#     'titling-caps': ['titl'],
# }
# 
# EAST_ASIAN_KEYS = {
#     'jis78': 'jp78',
#     'jis83': 'jp83',
#     'jis90': 'jp90',
#     'jis04': 'jp04',
#     'simplified': 'smpl',
#     'traditional': 'trad',
#     'full-width': 'fwid',
#     'proportional-width': 'pwid',
#     'ruby': 'ruby',
# }
# 
# FONTCONFIG_STRETCH = {
#     'normal': 'normal',
#     'ultra-condensed': 'ultracondensed',
#     'extra-condensed': 'extracondensed',
#     'condensed': 'condensed',
#     'semi-condensed': 'semicondensed',
#     'semi-expanded': 'semiexpanded',
#     'expanded': 'expanded',
#     'extra-expanded': 'extraexpanded',
#     'ultra-expanded': 'ultraexpanded',
# }
# 
# FONTCONFIG_STYLE = {
#     'normal': 'roman',
#     'italic': 'italic',
#     'oblique': 'oblique',
# }
# 
# FONTCONFIG_WEIGHT = {
#     'normal': 'normal',
#     'bold': 'bold',
#     100: 'thin',
#     200: 'extralight',
#     300: 'light',
#     400: 'normal',
#     500: 'medium',
#     600: 'demibold',
#     700: 'bold',
#     800: 'extrabold',
#     900: 'black',
# }
# 
# LIGATURE_KEYS = {
#     'common-ligatures': ['liga', 'clig'],
#     'historical-ligatures': ['hlig'],
#     'discretionary-ligatures': ['dlig'],
#     'contextual': ['calt'],
# }
# 
# NUMERIC_KEYS = {
#     'lining-nums': 'lnum',
#     'oldstyle-nums': 'onum',
#     'proportional-nums': 'pnum',
#     'tabular-nums': 'tnum',
#     'diagonal-fractions': 'frac',
#     'stacked-fractions': 'afrc',
#     'ordinal': 'ordn',
#     'slashed-zero': 'zero',
# }
# 
# Path: weasyprint/text/ffi.py
# def _dlopen(ffi, *names):
# def unicode_to_char_p(string):


import hashlib
import io
import os
import pathlib
import sys
import tempfile
import warnings
from fontTools.ttLib import TTFont, woff2
from ..logger import LOGGER
from ..urls import FILESYSTEM_ENCODING, fetch
from .constants import (
    CAPS_KEYS, EAST_ASIAN_KEYS, FONTCONFIG_STRETCH, FONTCONFIG_STYLE,
    FONTCONFIG_WEIGHT, LIGATURE_KEYS, NUMERIC_KEYS)
from .ffi import ffi, fontconfig, gobject, pangoft2
                    <test name="file" compare="eq">
                      <string>{font_filename}</string>
                    </test>
                    <edit name="family" mode="assign_replace">
                      <string>{rule_descriptors['font_family']}</string>
                    </edit>
                    <edit name="slant" mode="assign_replace">
                      <const>{fontconfig_style}</const>
                    </edit>
                    <edit name="weight" mode="assign_replace">
                      <const>{fontconfig_weight}</const>
                    </edit>
                    <edit name="width" mode="assign_replace">
                      <const>{fontconfig_stretch}</const>
                    </edit>
                  </match>
                  <match target="font">
                    <test name="file" compare="eq">
                      <string>{font_filename}</string>
                    </test>
                    <edit name="fontfeatures"
                          mode="assign_replace">{features_string}</edit>
                  </match>
                </fontconfig>'''
                fd = tempfile.NamedTemporaryFile(
                    'w', dir=self._tempdir, delete=False)
                fd.write(xml)
                fd.close()
                self._filenames.append(fd.name)
                fontconfig.FcConfigParseAndLoad(

# Path: weasyprint/logger.py
# LOGGER = logging.getLogger('weasyprint')
# 
# Path: weasyprint/urls.py
# FILESYSTEM_ENCODING = sys.getfilesystemencoding()
# 
# @contextlib.contextmanager
# def fetch(url_fetcher, url):
#     """Call an url_fetcher, fill in optional data, and clean up."""
#     try:
#         result = url_fetcher(url)
#     except Exception as exception:
#         raise URLFetchingError(f'{type(exception).__name__}: {exception}')
#     result.setdefault('redirected_url', url)
#     result.setdefault('mime_type', None)
#     if 'file_obj' in result:
#         try:
#             yield result
#         finally:
#             try:
#                 result['file_obj'].close()
#             except Exception:  # pragma: no cover
#                 # May already be closed or something.
#                 # This is just cleanup anyway: log but make it non-fatal.
#                 LOGGER.warning(
#                     'Error when closing stream for %s:\n%s',
#                     url, traceback.format_exc())
#     else:
#         yield result
# 
# Path: weasyprint/text/constants.py
# CAPS_KEYS = {
#     'small-caps': ['smcp'],
#     'all-small-caps': ['c2sc', 'smcp'],
#     'petite-caps': ['pcap'],
#     'all-petite-caps': ['c2pc', 'pcap'],
#     'unicase': ['unic'],
#     'titling-caps': ['titl'],
# }
# 
# EAST_ASIAN_KEYS = {
#     'jis78': 'jp78',
#     'jis83': 'jp83',
#     'jis90': 'jp90',
#     'jis04': 'jp04',
#     'simplified': 'smpl',
#     'traditional': 'trad',
#     'full-width': 'fwid',
#     'proportional-width': 'pwid',
#     'ruby': 'ruby',
# }
# 
# FONTCONFIG_STRETCH = {
#     'normal': 'normal',
#     'ultra-condensed': 'ultracondensed',
#     'extra-condensed': 'extracondensed',
#     'condensed': 'condensed',
#     'semi-condensed': 'semicondensed',
#     'semi-expanded': 'semiexpanded',
#     'expanded': 'expanded',
#     'extra-expanded': 'extraexpanded',
#     'ultra-expanded': 'ultraexpanded',
# }
# 
# FONTCONFIG_STYLE = {
#     'normal': 'roman',
#     'italic': 'italic',
#     'oblique': 'oblique',
# }
# 
# FONTCONFIG_WEIGHT = {
#     'normal': 'normal',
#     'bold': 'bold',
#     100: 'thin',
#     200: 'extralight',
#     300: 'light',
#     400: 'normal',
#     500: 'medium',
#     600: 'demibold',
#     700: 'bold',
#     800: 'extrabold',
#     900: 'black',
# }
# 
# LIGATURE_KEYS = {
#     'common-ligatures': ['liga', 'clig'],
#     'historical-ligatures': ['hlig'],
#     'discretionary-ligatures': ['dlig'],
#     'contextual': ['calt'],
# }
# 
# NUMERIC_KEYS = {
#     'lining-nums': 'lnum',
#     'oldstyle-nums': 'onum',
#     'proportional-nums': 'pnum',
#     'tabular-nums': 'tnum',
#     'diagonal-fractions': 'frac',
#     'stacked-fractions': 'afrc',
#     'ordinal': 'ordn',
#     'slashed-zero': 'zero',
# }
# 
# Path: weasyprint/text/ffi.py
# def _dlopen(ffi, *names):
# def unicode_to_char_p(string):


# Path: weasyprint/text/fonts.py
import hashlib
import io
import os
import pathlib
import sys
import tempfile
import warnings
from fontTools.ttLib import TTFont, woff2
from ..logger import LOGGER
from ..urls import FILESYSTEM_ENCODING, fetch
from .constants import (
    CAPS_KEYS, EAST_ASIAN_KEYS, FONTCONFIG_STRETCH, FONTCONFIG_STYLE,
    FONTCONFIG_WEIGHT, LIGATURE_KEYS, NUMERIC_KEYS)
from .ffi import ffi, fontconfig, gobject, pangoft2

                    <test name="file" compare="eq">
                      <string>{font_filename}</string>
                    </test>
                    <edit name="family" mode="assign_replace">
                      <string>{rule_descriptors['font_family']}</string>
                    </edit>
                    <edit name="slant" mode="assign_replace">
                      <const>{fontconfig_style}</const>
                    </edit>
                    <edit name="weight" mode="assign_replace">
                      <const>{fontconfig_weight}</const>
                    </edit>
                    <edit name="width" mode="assign_replace">
                      <const>{fontconfig_stretch}</const>
                    </edit>
                  </match>
                  <match target="font">
                    <test name="file" compare="eq">
                      <string>{font_filename}</string>
                    </test>
                    <edit name="fontfeatures"
                          mode="assign_replace">{features_string}</edit>
                  </match>
                </fontconfig>'''
                fd = tempfile.NamedTemporaryFile(
                    'w', dir=self._tempdir, delete=False)
                fd.write(xml)
                fd.close()
                self._filenames.append(fd.name)
                fontconfig.FcConfigParseAndLoad(

                    config, fd.name.encode(FILESYSTEM_ENCODING),