Source code for enable.trait_defs.kiva_font_trait

# (C) Copyright 2005-2022 Enthought, Inc., Austin, TX
# All rights reserved.
#
# This software is provided without warranty under the terms of the BSD
# license included in LICENSE.txt and may be redistributed only under
# the conditions described in the aforementioned license. The license
# is also available online at http://www.enthought.com/licenses/BSD.txt
#
# Thanks for using Enthought open source!
""" Trait definition for a wxPython-based Kiva font.
"""

from pyface.font import Font as PyfaceFont
from traits.api import DefaultValue, TraitError, TraitType, NoDefaultSpecified

import kiva.constants as kc
from kiva.fonttools.font import Font, FontParseError, simple_parser


#: Expected attributes on the Font class.
font_attrs = [
    'face_name', 'size', 'family', 'weight', 'style', 'underline', 'encoding',
]

#: Mapping from Pyface Font generic family names to corresponding constants.
pyface_family_to_kiva_family = {
    'default': kc.DEFAULT,
    'fantasy': kc.DECORATIVE,
    'decorative': kc.DECORATIVE,
    'serif': kc.ROMAN,
    'roman': kc.ROMAN,
    'cursive': kc.SCRIPT,
    'script': kc.SCRIPT,
    'sans-serif': kc.SWISS,
    'swiss': kc.SWISS,
    'monospace': kc.MODERN,
    'modern': kc.MODERN,
    'typewriter': kc.TELETYPE,
    'teletype': kc.TELETYPE,
}


[docs]def pyface_font_to_font(font): """Convert a Pyface font to an equivalent Kiva Font. This ignores stretch and some options like small caps and strikethrough as the Kiva font object can't represent these at the moment. Parameters ---------- font : Pyface Font instance The font to convert. Returns ------- font : Kiva Font instance The resulting Kiva Font object. """ face_name = font.family[0] for face in font.family: if face in pyface_family_to_kiva_family: family = pyface_family_to_kiva_family[face] break else: family = kc.DEFAULT size = int(font.size) weight = font.weight_ style = kc.NORMAL if font.style == 'normal' else kc.ITALIC underline = 'underline' in font.decorations return Font(face_name, size, family, weight, style, underline)
[docs]class KivaFont(TraitType): """ A Trait which casts strings to a Kiva Font value. """ #: The default value should be a tuple (factory, args, kwargs) default_value_type = DefaultValue.callable_and_args #: The parser to use when converting text to keyword args. This should #: accept a string and return a dictionary of Font class trait values (ie. #: "family", "size", "weight", etc.). If it can't parse the string, it #: should raise FontParseError. parser = None def __init__(self, default_value=None, *, parser=simple_parser, **metadata): # noqa: E501 self.parser = parser default_value = self._get_default_value(default_value) super().__init__(default_value, **metadata)
[docs] def validate(self, object, name, value): if isinstance(value, Font): return value if isinstance(value, PyfaceFont): return pyface_font_to_font(value) if isinstance(value, str): try: return Font(**self.parser(value)) except FontParseError: self.error(object, name, value) self.error(object, name, value)
[docs] def info(self): return ( "a Kiva Font, a Pyface Font, or a string describing a font" )
[docs] def get_editor(self, trait): from enable.trait_defs.ui.kiva_font_editor import KivaFontEditor return KivaFontEditor()
[docs] def clone(self, default_value=NoDefaultSpecified, **metadata): # Need to override clone due to Traits issue #1629 new = super().clone(NoDefaultSpecified, **metadata) if default_value is not NoDefaultSpecified: new.default_value = self._get_default_value(default_value) new.default_value_type = DefaultValue.callable_and_args return new
def _get_default_value(self, default_value): """Construct a default value suitable for callable_and_args.""" if default_value is not None: try: font = self.validate(None, None, default_value) except TraitError: raise ValueError( f"expected {self.info()}, but got {default_value!r}" ) klass = font.__class__ kwargs = {attr: getattr(font, attr) for attr in font_attrs} else: klass = Font kwargs = {} return (klass, (), kwargs)