1# ------------------------------------------------------------------------------
2#
3#  Copyright (c) 2005, Enthought, Inc.
4#  All rights reserved.
5#
6#  This software is provided without warranty under the terms of the BSD
7#  license included in LICENSE.txt and may be redistributed only
8#  under the conditions described in the aforementioned license.  The license
9#  is also available online at http://www.enthought.com/licenses/BSD.txt
10#
11#  Thanks for using Enthought open source!
12#
13#  Author: David C. Morrill
14#  Date:   02/14/2005
15#
16# ------------------------------------------------------------------------------
17
18""" Trait definition for a null-based (i.e., no UI) font.
19"""
20
21
22
23from traits.api import Trait, TraitHandler, TraitError
24
25# ------------------------------------------------------------------------------
26#  Convert a string into a valid 'wxFont' object (if possible):
27# ------------------------------------------------------------------------------
28
29# Mapping of strings to valid wxFont families
30font_families = ["default", "decorative", "roman", "script", "swiss", "modern"]
31
32# Mapping of strings to wxFont styles
33font_styles = ["slant", "italic"]
34
35# Mapping of strings wxFont weights
36font_weights = ["light", "bold"]
37
38# Strings to ignore in text representations of fonts
39font_noise = ["pt", "point", "family"]
40
41
42# ------------------------------------------------------------------------------
43#  'TraitFont' class'
44# ------------------------------------------------------------------------------
45
46
47class TraitFont(TraitHandler):
48    """ Ensures that values assigned to a trait attribute are valid font
49    descriptor strings; the value actually assigned is the corresponding
50    canonical font descriptor string.
51    """
52
53    def validate(self, object, name, value):
54        """ Validates that the value is a valid font descriptor string.
55        """
56        try:
57            point_size = family = style = weight = underline = ""
58            facename = [""]
59            for word in value.split():
60                lword = word.lower()
61                if lword in font_families:
62                    family = " " + lword
63                elif lword in font_styles:
64                    style = " " + lword
65                elif lword in font_weights:
66                    weight = " " + lword
67                elif lword == "underline":
68                    underline = " " + lword
69                elif lword not in font_noise:
70                    try:
71                        int(lword)
72                        point_size = lword + " pt"
73                    except:
74                        facename.append(word)
75            fontstr = (
76                "%s%s%s%s%s%s"
77                % (
78                    point_size,
79                    family,
80                    style,
81                    weight,
82                    underline,
83                    " ".join(facename),
84                )
85            ).strip()
86            return fontstr
87        except Exception:
88            pass
89        raise TraitError(object, name, "a font descriptor string", repr(value))
90
91    def info(self):
92        return (
93            "a string describing a font (e.g. '12 pt bold italic "
94            "swiss family Arial' or 'default 12')"
95        )
96
97
98# ------------------------------------------------------------------------------
99#  Define a 'null' specific font trait:
100# ------------------------------------------------------------------------------
101
102### Note: Declare the editor to be a function which returns the FontEditor
103# class from traits ui to avoid circular import issues. For backwards
104# compatibility with previous Traits versions, the 'editors' folder in Traits
105# project declares 'from api import *' in its __init__.py. The 'api' in turn
106# can contain classes that have a Font trait which lead to this file getting
107# imported. This leads to a circular import when declaring a Font trait.
108def get_font_editor(*args, **traits):
109    from ..api import FontEditor
110
111    return FontEditor(*args, **traits)
112
113
114fh = TraitFont()
115NullFont = Trait(
116    fh.validate(None, None, "Arial 10"), fh, editor=get_font_editor
117)
118