Skip to content

Commit

Permalink
Make classic testing work correctly
Browse files Browse the repository at this point in the history
Fix failures in #5416
  • Loading branch information
mdboom committed Nov 16, 2015
1 parent 174f9d8 commit baa2b6e
Show file tree
Hide file tree
Showing 11 changed files with 969 additions and 782 deletions.
4 changes: 4 additions & 0 deletions lib/matplotlib/afm.py
Expand Up @@ -523,6 +523,10 @@ def get_familyname(self):
br'light|ultralight|extra|condensed))+$')
return re.sub(extras, '', name)

@property
def family_name(self):
return self.get_familyname()

def get_weight(self):
"Return the font weight, e.g., 'Bold' or 'Roman'"
return self._header[b'Weight']
Expand Down
197 changes: 127 additions & 70 deletions lib/matplotlib/mathtext.py
Expand Up @@ -1240,58 +1240,115 @@ def get_underline_thickness(self, font, fontsize, dpi):
# The number of different sizes of chars to use, beyond which they will not
# get any smaller
NUM_SIZE_LEVELS = 6
# Percentage of x-height of additional horiz. space after sub/superscripts
SCRIPT_SPACE = {'cm': 0.075,
'stix': 0.10,
'stixsans': 0.05,
'dejavuserif': 0.05,
'dejavusans': 0.05}
## Percentage of x-height that sub/superscripts drop below the baseline
SUBDROP = {'cm': 0.2,
'stix': 0.4,
'stixsans': 0.4,
'dejavuserif': 0.4,
'dejavusans': 0.4}
# Percentage of x-height that superscripts are raised from the baseline
SUP1 = {'cm': 0.45,
'stix': 0.8,
'stixsans': 0.8,
'dejavuserif': 0.7,
'dejavusans': 0.7}
# Percentage of x-height that subscripts drop below the baseline
SUB1 = {'cm': 0.2,
'stix': 0.3,
'stixsans': 0.3,
'dejavuserif': 0.3,
'dejavusans': 0.3}
# Percentage of x-height that subscripts drop below the baseline when a
# superscript is present
SUB2 = {'cm': 0.3,
'stix': 0.6,
'stixsans': 0.5,
'dejavuserif': 0.5,
'dejavusans': 0.5}
# Percentage of x-height that sub/supercripts are offset relative to the
# nucleus edge for non-slanted nuclei
DELTA = {'cm': 0.075,
'stix': 0.05,
'stixsans': 0.025,
'dejavuserif': 0.025,
'dejavusans': 0.025}
# Additional percentage of last character height above 2/3 of the x-height that
# supercripts are offset relative to the subscript for slanted nuclei
DELTASLANTED = {'cm': 0.3,
'stix': 0.3,
'stixsans': 0.6,
'dejavuserif': 0.2,
'dejavusans': 0.2}
# Percentage of x-height that supercripts and subscripts are offset for
# integrals
DELTAINTEGRAL = {'cm': 0.3,
'stix': 0.3,
'stixsans': 0.3,
'dejavuserif': 0.1,
'dejavusans': 0.1}


class FontConstantsBase(object):
"""
A set of constants that controls how certain things, such as sub-
and superscripts are laid out. These are all metrics that can't
be reliably retrieved from the font metrics in the font itself.
"""
# Percentage of x-height of additional horiz. space after sub/superscripts
script_space = 0.05

# Percentage of x-height that sub/superscripts drop below the baseline
subdrop = 0.4

# Percentage of x-height that superscripts are raised from the baseline
sup1 = 0.7

# Percentage of x-height that subscripts drop below the baseline
sub1 = 0.3

# Percentage of x-height that subscripts drop below the baseline when a
# superscript is present
sub2 = 0.5

# Percentage of x-height that sub/supercripts are offset relative to the
# nucleus edge for non-slanted nuclei
delta = 0.025

# Additional percentage of last character height above 2/3 of the
# x-height that supercripts are offset relative to the subscript
# for slanted nuclei
delta_slanted = 0.2

# Percentage of x-height that supercripts and subscripts are offset for
# integrals
delta_integral = 0.1


class ComputerModernFontConstants(FontConstantsBase):
script_space = 0.075
subdrop = 0.2
sup1 = 0.45
sub1 = 0.2
sub2 = 0.3
delta = 0.075
delta_slanted = 0.3
delta_integral = 0.3


class STIXFontConstants(FontConstantsBase):
script_space = 0.1
sup1 = 0.8
sub2 = 0.6
delta = 0.05
delta_slanted = 0.3
delta_integral = 0.3


class STIXSansFontConstants(FontConstantsBase):
script_space = 0.05
sup1 = 0.8
delta_slanted = 0.6
delta_integral = 0.3


class DejaVuSerifFontConstants(FontConstantsBase):
pass


class DejaVuSansFontConstants(FontConstantsBase):
pass


# Maps font family names to the FontConstantBase subclass to use
_font_constant_mapping = {
'DejaVu Sans': DejaVuSansFontConstants,
'DejaVu Sans Mono': DejaVuSansFontConstants,
'DejaVu Serif': DejaVuSerifFontConstants,
'cmb10': ComputerModernFontConstants,
'cmex10': ComputerModernFontConstants,
'cmmi10': ComputerModernFontConstants,
'cmr10': ComputerModernFontConstants,
'cmss10': ComputerModernFontConstants,
'cmsy10': ComputerModernFontConstants,
'cmtt10': ComputerModernFontConstants,
'STIXGeneral': STIXFontConstants,
'STIXNonUnicode': STIXFontConstants,
'STIXSizeFiveSym': STIXFontConstants,
'STIXSizeFourSym': STIXFontConstants,
'STIXSizeThreeSym': STIXFontConstants,
'STIXSizeTwoSym': STIXFontConstants,
'STIXSizeOneSym': STIXFontConstants,
# Map the fonts we used to ship, just for good measure
'Bitstream Vera Sans': DejaVuSansFontConstants,
'Bitstream Vera': DejaVuSansFontConstants,
}


def _get_font_constant_set(state):
constants = _font_constant_mapping.get(
state.font_output._get_font(state.font).family_name,
FontConstantsBase)
# STIX sans isn't really its own fonts, just different code points
# in the STIX fonts, so we have to detect this one separately.
if (constants is STIXFontConstants and
isinstance(state.font_output, StixSansFonts)):
return STIXSansFontConstants
return constants


class MathTextWarning(Warning):
pass
Expand Down Expand Up @@ -2873,25 +2930,24 @@ def subsuper(self, s, loc, toks):
nucleus = Hlist([nucleus])

# Handle regular sub/superscripts

fs = rcParams['mathtext.fontset']
if fs == 'custom':
fs = 'dejavusans'

constants = _get_font_constant_set(state)
lc_height = last_char.height
lc_baseline = 0
if self.is_dropsub(last_char):
lc_baseline = last_char.depth

# Compute kerning for sub and super
superkern = DELTA[fs] * xHeight
subkern = DELTA[fs] * xHeight
superkern = constants.delta * xHeight
subkern = constants.delta * xHeight
if self.is_slanted(last_char):
superkern += DELTA[fs] * xHeight
superkern += DELTASLANTED[fs] * (lc_height - xHeight * 2. / 3.)
superkern += constants.delta * xHeight
superkern += (constants.delta_slanted *
(lc_height - xHeight * 2. / 3.))
if self.is_dropsub(last_char):
subkern = (3 * DELTA[fs] - DELTAINTEGRAL[fs]) * lc_height
superkern = (3 * DELTA[fs] + DELTAINTEGRAL[fs]) * lc_height
subkern = (3 * constants.delta -
constants.delta_integral) * lc_height
superkern = (3 * constants.delta +
constants.delta_integral) * lc_height
else:
subkern = 0

Expand All @@ -2900,26 +2956,26 @@ def subsuper(self, s, loc, toks):
x = Hlist([Kern(subkern), sub])
x.shrink()
if self.is_dropsub(last_char):
shift_down = lc_baseline + SUBDROP[fs] * xHeight
shift_down = lc_baseline + constants.subdrop * xHeight
else:
shift_down = SUB1[fs] * xHeight
shift_down = constants.sub1 * xHeight
x.shift_amount = shift_down
else:
x = Hlist([Kern(superkern), super])
x.shrink()
if self.is_dropsub(last_char):
shift_up = lc_height - SUBDROP[fs] * xHeight
shift_up = lc_height - constants.subdrop * xHeight
else:
shift_up = SUP1[fs] * xHeight
shift_up = constants.sup1 * xHeight
if sub is None:
x.shift_amount = -shift_up
else: # Both sub and superscript
y = Hlist([Kern(subkern),sub])
y.shrink()
if self.is_dropsub(last_char):
shift_down = lc_baseline + SUBDROP[fs] * xHeight
shift_down = lc_baseline + constants.subdrop * xHeight
else:
shift_down = SUB2[fs] * xHeight
shift_down = constants.sub2 * xHeight
# If sub and superscript collide, move super up
clr = (2.0 * rule_thickness -
((shift_up - x.depth) - (y.height - shift_down)))
Expand All @@ -2931,8 +2987,9 @@ def subsuper(self, s, loc, toks):
x.shift_amount = shift_down

if not self.is_dropsub(last_char):
x.width += SCRIPT_SPACE[fs] * xHeight
x.width += constants.script_space * xHeight
result = Hlist([nucleus, x])

return [result]

def _genfrac(self, ldelim, rdelim, rule, style, num, den):
Expand Down
6 changes: 3 additions & 3 deletions lib/matplotlib/mpl-data/stylelib/classic.mplstyle
Expand Up @@ -76,11 +76,11 @@ font.stretch : normal
# relative to font.size, using the following values: xx-small, x-small,
# small, medium, large, x-large, xx-large, larger, or smaller
font.size : 12.0
font.serif : Bitstream Vera Serif, DejaVu Serif, New Century Schoolbook, Century Schoolbook L, Utopia, ITC Bookman, Bookman, Nimbus Roman No9 L, Times New Roman, Times, Palatino, Charter, serif
font.sans-serif: Bitstream Vera Sans, DejaVu Sans, Lucida Grande, Verdana, Geneva, Lucid, Arial, Helvetica, Avant Garde, sans-serif
font.serif : DejaVu Serif, New Century Schoolbook, Century Schoolbook L, Utopia, ITC Bookman, Bookman, Nimbus Roman No9 L, Times New Roman, Times, Palatino, Charter, serif
font.sans-serif: DejaVu Sans, Lucida Grande, Verdana, Geneva, Lucid, Arial, Helvetica, Avant Garde, sans-serif
font.cursive : Apple Chancery, Textile, Zapf Chancery, Sand, Script MT, Felipa, cursive
font.fantasy : Comic Sans MS, Chicago, Charcoal, ImpactWestern, Humor Sans, fantasy
font.monospace : Bitstream Vera Sans Mono, DejaVu Sans Mono, Andale Mono, Nimbus Mono L, Courier New, Courier, Fixed, Terminal, monospace
font.monospace : DejaVu Sans Mono, Andale Mono, Nimbus Mono L, Courier New, Courier, Fixed, Terminal, monospace

### TEXT
# text properties used by text.Text. See
Expand Down
38 changes: 23 additions & 15 deletions lib/matplotlib/testing/decorators.py
Expand Up @@ -22,6 +22,7 @@
from matplotlib import ticker
from matplotlib import pyplot as plt
from matplotlib import ft2font
from matplotlib import rcParams
from matplotlib.testing.noseclasses import KnownFailureTest, \
KnownFailureDidNotFailTest, ImageComparisonFailure
from matplotlib.testing.compare import comparable_formats, compare_images, \
Expand Down Expand Up @@ -109,18 +110,27 @@ def tearDownClass(cls):
cls.original_settings)


def cleanup(func):
@functools.wraps(func)
def wrapped_function(*args, **kwargs):
original_units_registry = matplotlib.units.registry.copy()
original_settings = mpl.rcParams.copy()
try:
func(*args, **kwargs)
finally:
_do_cleanup(original_units_registry,
original_settings)
def cleanup(style=None):
def make_cleanup(func):
@functools.wraps(func)
def wrapped_function(*args, **kwargs):
original_units_registry = matplotlib.units.registry.copy()
original_settings = mpl.rcParams.copy()
matplotlib.style.use(style)
try:
func(*args, **kwargs)
finally:
_do_cleanup(original_units_registry,
original_settings)

return wrapped_function
return wrapped_function

if isinstance(style, six.string_types):
return make_cleanup
else:
result = make_cleanup(style)
style = 'classic'
return result


def check_freetype_version(ver):
Expand All @@ -138,6 +148,7 @@ def check_freetype_version(ver):
class ImageComparisonTest(CleanupTest):
@classmethod
def setup_class(cls):
CleanupTest.setup_class()
cls._initial_settings = mpl.rcParams.copy()
try:
matplotlib.style.use(cls._style)
Expand All @@ -146,11 +157,8 @@ def setup_class(cls):
mpl.rcParams.clear()
mpl.rcParams.update(cls._initial_settings)
raise
# Because the setup of a CleanupTest might involve
# modifying a few rcparams, this setup should come
# last prior to running the image test.
CleanupTest.setup_class()
cls.original_settings = cls._initial_settings
matplotlib.tests.set_font_settings_for_testing()
cls._func()

@classmethod
Expand Down
11 changes: 8 additions & 3 deletions lib/matplotlib/tests/__init__.py
Expand Up @@ -22,6 +22,12 @@
'test data.')


def set_font_settings_for_testing():
rcParams['font.family'] = 'DejaVu Sans'
rcParams['text.hinting'] = False
rcParams['text.hinting_factor'] = 8


def setup():
# The baseline images are created in this locale, so we should use
# it during all of the tests.
Expand All @@ -45,9 +51,8 @@ def setup():
# tests and are not necessarily the default values as specified in
# rcsetup.py
rcdefaults() # Start with all defaults
rcParams['font.family'] = 'DejaVu Sans'
rcParams['text.hinting'] = False
rcParams['text.hinting_factor'] = 8

set_font_settings_for_testing()


def assert_str_equal(reference_str, test_str,
Expand Down
Binary file modified lib/matplotlib/tests/baseline_images/test_axes/symlog.pdf
Binary file not shown.
Binary file modified lib/matplotlib/tests/baseline_images/test_axes/symlog.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit baa2b6e

Please sign in to comment.