Spaces:
Running
Running
| from io import BytesIO | |
| import pytest | |
| import logging | |
| from matplotlib import _afm | |
| from matplotlib import font_manager as fm | |
| # See note in afm.py re: use of comma as decimal separator in the | |
| # UnderlineThickness field and re: use of non-ASCII characters in the Notice | |
| # field. | |
| AFM_TEST_DATA = b"""StartFontMetrics 2.0 | |
| Comment Comments are ignored. | |
| Comment Creation Date:Mon Nov 13 12:34:11 GMT 2017 | |
| FontName MyFont-Bold | |
| EncodingScheme FontSpecific | |
| FullName My Font Bold | |
| FamilyName Test Fonts | |
| Weight Bold | |
| ItalicAngle 0.0 | |
| IsFixedPitch false | |
| UnderlinePosition -100 | |
| UnderlineThickness 56,789 | |
| Version 001.000 | |
| Notice Copyright \xa9 2017 No one. | |
| FontBBox 0 -321 1234 369 | |
| StartCharMetrics 3 | |
| C 0 ; WX 250 ; N space ; B 0 0 0 0 ; | |
| C 42 ; WX 1141 ; N foo ; B 40 60 800 360 ; | |
| C 99 ; WX 583 ; N bar ; B 40 -10 543 210 ; | |
| EndCharMetrics | |
| EndFontMetrics | |
| """ | |
| def test_nonascii_str(): | |
| # This tests that we also decode bytes as utf-8 properly. | |
| # Else, font files with non ascii characters fail to load. | |
| inp_str = "привет" | |
| byte_str = inp_str.encode("utf8") | |
| ret = _afm._to_str(byte_str) | |
| assert ret == inp_str | |
| def test_parse_header(): | |
| fh = BytesIO(AFM_TEST_DATA) | |
| header = _afm._parse_header(fh) | |
| assert header == { | |
| b'StartFontMetrics': 2.0, | |
| b'FontName': 'MyFont-Bold', | |
| b'EncodingScheme': 'FontSpecific', | |
| b'FullName': 'My Font Bold', | |
| b'FamilyName': 'Test Fonts', | |
| b'Weight': 'Bold', | |
| b'ItalicAngle': 0.0, | |
| b'IsFixedPitch': False, | |
| b'UnderlinePosition': -100, | |
| b'UnderlineThickness': 56.789, | |
| b'Version': '001.000', | |
| b'Notice': b'Copyright \xa9 2017 No one.', | |
| b'FontBBox': [0, -321, 1234, 369], | |
| b'StartCharMetrics': 3, | |
| } | |
| def test_parse_char_metrics(): | |
| fh = BytesIO(AFM_TEST_DATA) | |
| _afm._parse_header(fh) # position | |
| metrics = _afm._parse_char_metrics(fh) | |
| assert metrics == ( | |
| {0: (250.0, 'space', [0, 0, 0, 0]), | |
| 42: (1141.0, 'foo', [40, 60, 800, 360]), | |
| 99: (583.0, 'bar', [40, -10, 543, 210]), | |
| }, | |
| {'space': (250.0, 'space', [0, 0, 0, 0]), | |
| 'foo': (1141.0, 'foo', [40, 60, 800, 360]), | |
| 'bar': (583.0, 'bar', [40, -10, 543, 210]), | |
| }) | |
| def test_get_familyname_guessed(): | |
| fh = BytesIO(AFM_TEST_DATA) | |
| font = _afm.AFM(fh) | |
| del font._header[b'FamilyName'] # remove FamilyName, so we have to guess | |
| assert font.get_familyname() == 'My Font' | |
| def test_font_manager_weight_normalization(): | |
| font = _afm.AFM(BytesIO( | |
| AFM_TEST_DATA.replace(b"Weight Bold\n", b"Weight Custom\n"))) | |
| assert fm.afmFontProperty("", font).weight == "normal" | |
| def test_bad_afm(afm_data): | |
| fh = BytesIO(afm_data) | |
| with pytest.raises(RuntimeError): | |
| _afm._parse_header(fh) | |
| def test_malformed_header(afm_data, caplog): | |
| fh = BytesIO(afm_data) | |
| with caplog.at_level(logging.ERROR): | |
| _afm._parse_header(fh) | |
| assert len(caplog.records) == 1 | |