File: Designspaces%20with%20python.md

package info (click to toggle)
ufoprocessor 1.13.3-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 1,460 kB
  • sloc: python: 3,126; makefile: 5
file content (120 lines) | stat: -rw-r--r-- 4,330 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
# Designspaces and python

Designspaces can do different things in different processes. Maybe you want to generate a variable font. Maybe you want to generate UFOs. Maybe you want to resample an existing designspace into something else. 
While [fonttools.designspacelib](https://fonttools.readthedocs.io/en/latest/designspaceLib/index.html) contains the basic objects to construct, read and write designspaces, the [ufoProcessor package](https://github.com/LettError/ufoProcessor) can also generate instances. 

## Basics
First I have to make a `DesignSpaceDocument` object. This is an empty container, it has no masters, no axes, no path.

    from fontTools.designspaceLib import *
    ds = DesignSpaceDocument()
        
Now I will add an axis to the document by making an `AxisDescriptor` object and adding some values to its attributes.

    ad = AxisDescriptor()
    ad.name = "weight" # readable name
    ad.tag = "wght" 	 # 4 letter tag
    ad.minimum = 200
    ad.maximum = 1000
    ad.default = 400

Finally we add the axisDescriptor to the document:

    ds.addAxis(ad)
    print(ds)
    path = "my.designspace"
    ds.write(path)

This writes a very small designspace file:   
    
    <?xml version='1.0' encoding='UTF-8'?>
        <designspace format="4.0">
        <axes>
            <axis tag="wght" name="weight" minimum="200" maximum="1000" default="400"/>
        </axes>
    </designspace>

Let's add some sources to the designspace: this needs the absolute path to the file (usually a ufo). When the document is saved the paths will be written as relative to the designspace document. A `SourceDescriptor` object has a lot of attributes, but `path` and `location` are the most important ones.

    s1 = SourceDescriptor()
    s1.path = "geometryMaster1.ufo"
    s1.location = dict(weight=200)
    ds.addSource(s1)

    s2 = SourceDescriptor()
    s2.path = "geometryMaster2.ufo"
    s2.location = dict(weight=1000)
    ds.addSource(s2)

Let's add some instances. Instances are specific locations in the designspace with names and sometimes paths associated with them. In a variable font you might want these to show up as styles in a menu. But you could also generate UFOs from them.

    for w in [ad.minimum, .5*(ad.minimum + ad.default), ad.default, .5*(ad.maximum + ad.default), ad.maximum]:
        # you will probably know more compact
        # and easier ways to write this, go ahead!
        i = InstanceDescriptor()
        i.fileName = "InstanceFamily"
        i.styleName = "Weight_%d" % w
        i.location = dict(weight = w)
        i.filename = "instance_%s.ufo" % i.styleName
        ds.addInstance(i)
        
The XML now has all it needs: an axis, some sources and ome instances.

	<?xml version='1.0' encoding='UTF-8'?>
	<designspace format="4.0">
	  <axes>
	    <axis tag="wght" name="weight" minimum="200" maximum="1000" default="400"/>
	  </axes>
	  <sources>
	    <source filename="geometryMaster1.ufo">
	      <location>
	        <dimension name="weight" xvalue="200"/>
	      </location>
	    </source>
	    <source filename="geometryMaster2.ufo">
	      <location>
	        <dimension name="weight" xvalue="1000"/>
	      </location>
	    </source>
	  </sources>
	  <instances>
	    <instance stylename="Weight_200" filename="instance_Weight_200.ufo">
	      <location>
	        <dimension name="weight" xvalue="200"/>
	      </location>
	      <kerning/>
	      <info/>
	    </instance>
	    <instance stylename="Weight_300" filename="instance_Weight_300.ufo">
	      <location>
	        <dimension name="weight" xvalue="300"/>
	      </location>
	      <kerning/>
	      <info/>
	    </instance>
	    <instance stylename="Weight_400" filename="instance_Weight_400.ufo">
	      <location>
	        <dimension name="weight" xvalue="400"/>
	      </location>
	      <kerning/>
	      <info/>
	    </instance>
	    <instance stylename="Weight_700" filename="instance_Weight_700.ufo">
	      <location>
	        <dimension name="weight" xvalue="700"/>
	      </location>
	      <kerning/>
	      <info/>
	    </instance>
	    <instance stylename="Weight_1000" filename="instance_Weight_1000.ufo">
	      <location>
	        <dimension name="weight" xvalue="1000"/>
	      </location>
	      <kerning/>
	      <info/>
	    </instance>
	  </instances>
	</designspace>

Whoop well done.